Update Mechanism
parent
61e4e44767
commit
0310a7f94b
|
@ -10,17 +10,22 @@
|
|||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.8.4",
|
||||
"cron": "^4.1.3",
|
||||
"dayjs": "^1.11.13",
|
||||
"js-cookie": "^3.0.5",
|
||||
"preline": "^2.4.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-fast-marquee": "^1.6.5",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-icons": "^5.3.0",
|
||||
"react-qr-code": "^2.0.15",
|
||||
"react-router-dom": "^6.26.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
const MODE: "dev" | "staging" | "prod" = "dev";
|
||||
|
||||
const DEV_HOST = "http://next-api.ferinesia.local";
|
||||
const STAGING_HOST = "";
|
||||
const PROD_HOST = "https://prod-api-2.ferinesia.com";
|
||||
|
||||
const CURRENT_HOST: Record<"dev" | "staging" | "prod", string> = {
|
||||
dev: DEV_HOST,
|
||||
staging: STAGING_HOST,
|
||||
prod: PROD_HOST
|
||||
};
|
||||
|
||||
const endpoints = {
|
||||
me: "/user/api/authentication/schedule_board/me",
|
||||
qr_code_login: "/user/api/authentication/schedule_board/login_token",
|
||||
login: "/user/api/authentication/schedule_board/login",
|
||||
schedule_entries: "/schedules/api/schedule_board/get_schedule_entries"
|
||||
}
|
||||
|
||||
const activeHost = CURRENT_HOST[MODE];
|
||||
|
||||
export {activeHost, endpoints};
|
|
@ -0,0 +1,21 @@
|
|||
import { activeHost } from "@/config/host";
|
||||
import axios from "axios";
|
||||
|
||||
interface AxiosInstanceProp
|
||||
{
|
||||
bearerToken?: string
|
||||
}
|
||||
|
||||
|
||||
const createAxiosInstance = (prop: AxiosInstanceProp) => {
|
||||
const axiosInstance = axios.create({
|
||||
baseURL: activeHost,
|
||||
headers: {
|
||||
"Authorization": `Bearer ${prop.bearerToken}`
|
||||
}
|
||||
});
|
||||
|
||||
return axiosInstance;
|
||||
}
|
||||
|
||||
export {createAxiosInstance};
|
|
@ -5,3 +5,14 @@
|
|||
html{
|
||||
font-family: 'Inter';
|
||||
}
|
||||
|
||||
/* HTML: <div class="loader"></div> */
|
||||
.loader {
|
||||
width: 50px;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 50%;
|
||||
border: 8px solid;
|
||||
border-color: #000 #0000;
|
||||
animation: l1 1s infinite;
|
||||
}
|
||||
@keyframes l1 {to{transform: rotate(.5turn)}}
|
|
@ -5,6 +5,7 @@ import { createHashRouter, RouterProvider } from 'react-router-dom'
|
|||
import {Index as HomepageIndex} from '@/pages/homepage'
|
||||
import {Helmet} from "react-helmet"
|
||||
import Login from '@/pages/auth/login'
|
||||
import QRCodeLogin from './pages/auth/qr-code-scan'
|
||||
|
||||
const router = createHashRouter([
|
||||
{
|
||||
|
@ -14,7 +15,11 @@ const router = createHashRouter([
|
|||
{
|
||||
path: "/login",
|
||||
element: <Login />
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/qr-login",
|
||||
element: <QRCodeLogin />
|
||||
},
|
||||
])
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
|
|
|
@ -1,22 +1,77 @@
|
|||
import ferinesiaLogo from "@/assets/logos/ferinesia-logo-thin.png"
|
||||
import { useEffect, useState } from "react"
|
||||
import { useLocation } from "react-router-dom"
|
||||
import ferinesiaLogo from "@/assets/logos/ferinesia-logo-thin.png";
|
||||
import { endpoints } from "@/config/host";
|
||||
import { createAxiosInstance } from "@/functions/axios-instance";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useLocation, useSearchParams } from "react-router-dom";
|
||||
import Cookies from "js-cookie";
|
||||
import { AxiosError } from "axios";
|
||||
|
||||
/**
|
||||
* Copyright: Task Master (https://tailwindflex.com/@task_master)
|
||||
* URL: https://tailwindflex.com/@task_master/login-form-with-social-login-buttons
|
||||
*/
|
||||
|
||||
export interface InputValidationError{
|
||||
type: string,
|
||||
message: string
|
||||
export interface InputValidationError {
|
||||
type: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export default function Login() {
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
const [username, setUsername] = useState("")
|
||||
const [password, setPassword] = useState("")
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [loginToken, setLoginToken] = useState<string | null>(null);
|
||||
const [terminalID, setTerminalID] = useState<string | null>(null);
|
||||
|
||||
const [isSuccessLogin, setIsSuccessLogin] = useState<boolean | null>(null);
|
||||
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
const [inputValidationMsg, setInputValidationMsg] = useState<InputValidationError[]>([]);
|
||||
|
||||
const doLogin = async () => {
|
||||
let validationErrors = []
|
||||
if(username.length <= 0){
|
||||
validationErrors.push({type: "username", message: "Username tidak boleh kosong"})
|
||||
}
|
||||
if(password.length <= 0){
|
||||
validationErrors.push({type: "password", message: "Password tidak boleh kosong"})
|
||||
}
|
||||
setInputValidationMsg(validationErrors)
|
||||
|
||||
if(validationErrors.length > 0)
|
||||
return
|
||||
|
||||
setIsLoading(true)
|
||||
try{
|
||||
const {data} = await createAxiosInstance({}).post(endpoints.login, {
|
||||
username,
|
||||
password,
|
||||
token: loginToken
|
||||
});
|
||||
setIsSuccessLogin(true);
|
||||
return
|
||||
}
|
||||
catch(err){
|
||||
if(err instanceof AxiosError){
|
||||
if(err.response?.data?.meta?.is_error){
|
||||
validationErrors.push({type: "username", message: err.response?.data?.meta?.message})
|
||||
}
|
||||
}
|
||||
else
|
||||
validationErrors.push({type: "username", message: "Terjadi kesalahan saat memproses data"})
|
||||
}
|
||||
finally{
|
||||
setInputValidationMsg(validationErrors)
|
||||
setIsLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setLoginToken(searchParams.get("state") ?? null);
|
||||
setTerminalID(searchParams.get("terminal_id") ?? null);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-100 flex flex-col justify-center sm:py-12">
|
||||
|
@ -29,67 +84,102 @@ export default function Login() {
|
|||
</h1>
|
||||
</div>
|
||||
<div className="bg-white shadow w-full rounded-lg pt-4 pb-4">
|
||||
<div className="px-5 py-2">
|
||||
<label className="font-semibold text-sm text-gray-600 pb-1 block">
|
||||
Username
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="border rounded-lg px-3 py-2 mt-1 mb-1 text-sm w-full"
|
||||
onInput={e => setUsername(e.currentTarget.value)}
|
||||
/>
|
||||
{/* {
|
||||
inputValidationMsg.find(x => x.type == "username") &&
|
||||
<span className="text-red-500">{inputValidationMsg.find(x => x.type == "username")!.message}</span>
|
||||
} */}
|
||||
</div>
|
||||
<div className="px-5 py-2">
|
||||
<label className="font-semibold text-sm text-gray-600 pb-1 block">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
className="border rounded-lg px-3 py-2 mt-1 mb-1 text-sm w-full"
|
||||
onInput={e => setPassword(e.currentTarget.value)}
|
||||
/>
|
||||
{/* {
|
||||
inputValidationMsg.find(x => x.type == "password") &&
|
||||
<span className="text-red-500">{inputValidationMsg.find(x => x.type == "password")!.message}</span>
|
||||
} */}
|
||||
</div>
|
||||
<div className="px-5 py-2">
|
||||
<button
|
||||
// onClick={doLogin}
|
||||
disabled={isLoading}
|
||||
type="button"
|
||||
className="transition duration-200 bg-blue-500 hover:bg-blue-600 focus:bg-blue-700 focus:shadow-sm focus:ring-4 focus:ring-blue-500 focus:ring-opacity-50 text-white w-full py-2.5 rounded-lg text-sm shadow-sm hover:shadow-md font-semibold text-center flex flex-row justify-center align-middle items-center disabled:bg-gray-300"
|
||||
>
|
||||
{
|
||||
isLoading && <span className="animate-spin inline-block size-4 border-[3px] border-current border-t-transparent text-white rounded-full mr-2" role="status" aria-label="loading">
|
||||
<span className="sr-only">Loading...</span>
|
||||
</span>
|
||||
}
|
||||
<span className="inline-block mr-2">{isLoading ? "Mohon Tunggu" : "Login"}</span>
|
||||
{
|
||||
!isLoading && <svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
className="w-4 h-4 inline-block"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M17 8l4 4m0 0l-4 4m4-4H3"
|
||||
{
|
||||
(isSuccessLogin == null || !isSuccessLogin) && <>
|
||||
<div className="px-5 py-2">
|
||||
<label className="font-semibold text-sm text-gray-600 pb-1 block">
|
||||
Terminal ID
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="border rounded-lg px-3 py-2 mt-1 mb-1 text-sm w-full"
|
||||
value={terminalID ?? "N/A"}
|
||||
disabled
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
{/* {
|
||||
inputValidationMsg.find(x => x.type == "username") &&
|
||||
<span className="text-red-500">{inputValidationMsg.find(x => x.type == "username")!.message}</span>
|
||||
} */}
|
||||
</div>
|
||||
<div className="px-5 py-2">
|
||||
<label className="font-semibold text-sm text-gray-600 pb-1 block">
|
||||
Username
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="border rounded-lg px-3 py-2 mt-1 mb-1 text-sm w-full"
|
||||
onInput={(e) => setUsername(e.currentTarget.value)}
|
||||
/>
|
||||
{
|
||||
inputValidationMsg.find(x => x.type == "username") &&
|
||||
<span className="text-red-500">{inputValidationMsg.find(x => x.type == "username")!.message}</span>
|
||||
}
|
||||
</div>
|
||||
<div className="px-5 py-2">
|
||||
<label className="font-semibold text-sm text-gray-600 pb-1 block">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
className="border rounded-lg px-3 py-2 mt-1 mb-1 text-sm w-full"
|
||||
onInput={(e) => setPassword(e.currentTarget.value)}
|
||||
/>
|
||||
{
|
||||
inputValidationMsg.find(x => x.type == "password") &&
|
||||
<span className="text-red-500">{inputValidationMsg.find(x => x.type == "password")!.message}</span>
|
||||
}
|
||||
</div>
|
||||
<div className="px-5 py-2">
|
||||
{terminalID != null && loginToken != null && (
|
||||
<button
|
||||
onClick={doLogin}
|
||||
disabled={isLoading}
|
||||
type="button"
|
||||
className="transition duration-200 bg-blue-500 hover:bg-blue-600 focus:bg-blue-700 focus:shadow-sm focus:ring-4 focus:ring-blue-500 focus:ring-opacity-50 text-white w-full py-2.5 rounded-lg text-sm shadow-sm hover:shadow-md font-semibold text-center flex flex-row justify-center align-middle items-center disabled:bg-gray-300"
|
||||
>
|
||||
{isLoading && (
|
||||
<span
|
||||
className="animate-spin inline-block size-4 border-[3px] border-current border-t-transparent text-white rounded-full mr-2"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
>
|
||||
<span className="sr-only">Loading...</span>
|
||||
</span>
|
||||
)}
|
||||
<span className="inline-block mr-2">
|
||||
{isLoading ? "Mohon Tunggu" : "Login"}
|
||||
</span>
|
||||
{!isLoading && (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
className="w-4 h-4 inline-block"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M17 8l4 4m0 0l-4 4m4-4H3"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
||||
{(terminalID == null || loginToken == null) && <span className="text-[#ff0015]">Terminal ID dan Token Akses tidak valid.</span>}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
{
|
||||
isSuccessLogin && <div className="px-5 py-2">
|
||||
<h4 className="text-xl text-green-600 text-center">Sukses</h4>
|
||||
<h5 className="text-lg text-center mt-4">Berhasil melakukan login untuk penampil jadwal. Anda dapat menutup halaman ini.</h5>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
import ferinesiaLogo from "@/assets/logos/ferinesia-logo-thin.png";
|
||||
import { endpoints } from "@/config/host";
|
||||
import { createAxiosInstance } from "@/functions/axios-instance";
|
||||
import { useEffect, useState } from "react";
|
||||
import QRCode from "react-qr-code";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
export default function QRCodeLogin() {
|
||||
const [isLoadingQR, setIsLoadingQR] = useState(true);
|
||||
const [terminalID, setTerminalID] = useState<string | null>(null);
|
||||
const [qrCodeLogin, setQRCodeLogin] = useState<string | null>(null);
|
||||
|
||||
const getQRCodeLogin = async () => {
|
||||
try{
|
||||
const {data} = await createAxiosInstance({}).get(endpoints.qr_code_login);
|
||||
const loginToken = data.data.token;
|
||||
setQRCodeLogin(`https://schedule-board.ferinesia.com/#/login?state=${loginToken}&terminal_id=${data.data.terminal_id}`);
|
||||
setTerminalID(data.data.terminal_id);
|
||||
setIsLoadingQR(false);
|
||||
|
||||
setInterval(async () => {
|
||||
try{
|
||||
const {data} = await createAxiosInstance({bearerToken: loginToken}).get(endpoints.me);
|
||||
localStorage.setItem("HARBOR_NAME", data.data.harbor.name);
|
||||
localStorage.setItem("HARBOR_ADDRESS", data.data.harbor.address);
|
||||
Cookies.set("ferinesia_schedule_board_token", loginToken);
|
||||
location.href = "/";
|
||||
}
|
||||
catch(err){
|
||||
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
setInterval(() => {
|
||||
location.reload();
|
||||
}, 5 * 60 * 1000);
|
||||
}
|
||||
catch(err){
|
||||
alert("Tidak dapat mengambil QRCode, silahkan coba kembali.");
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getQRCodeLogin();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="min-h-screen bg-gray-100 flex flex-col justify-center sm:py-12">
|
||||
<div className="ml-8 mr-8">
|
||||
<div className="grid grid-cols-12 gap-4">
|
||||
<div className="col-span-6 border h-[600px] flex items-center justify-center flex-col">
|
||||
{isLoadingQR && (
|
||||
<div>
|
||||
<div className="loader"></div>
|
||||
</div>
|
||||
)}
|
||||
{!isLoadingQR && qrCodeLogin != null && (
|
||||
<QRCode size={512} value={qrCodeLogin} />
|
||||
)}
|
||||
{
|
||||
!isLoadingQR && <span className="mt-4 text-xl">Terminal ID: {terminalID ?? "N/A"}</span>
|
||||
}
|
||||
</div>
|
||||
<div className="col-span-6 p-4 border">
|
||||
<div className="flex items-center">
|
||||
<img src={ferinesiaLogo} className="max-h-6" />
|
||||
<h3 className="ml-2 text-2xl font-bold text-[#117AD1]">
|
||||
FERI<span className="text-[#FFCE46]">NESIA</span>
|
||||
</h3>
|
||||
</div>
|
||||
<h4 className="text-xl mt-8">
|
||||
Silahkan melakukan login dengan mengunjungi URL yang tesedia
|
||||
pada QRCode disebelah kiri.
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -21,6 +21,11 @@ import { useEffect, useState } from "react";
|
|||
import importData from "@/data/17_10_2024_TTE_BASTIONG.json";
|
||||
import importCompanyInfo from "@/data/LogoLocation.json";
|
||||
import { ScheduleStatus } from "@/constants/ScheduleStatus";
|
||||
import Cookies from "js-cookie";
|
||||
import { createAxiosInstance } from "@/functions/axios-instance";
|
||||
import { AxiosError } from "axios";
|
||||
import { endpoints } from "@/config/host";
|
||||
import { CronJob } from 'cron';
|
||||
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(timezone);
|
||||
|
@ -35,11 +40,21 @@ interface Schedule {
|
|||
ship_name: string;
|
||||
}
|
||||
|
||||
interface AccountInfo {
|
||||
harbor: {
|
||||
name: string;
|
||||
address: string;
|
||||
code: string;
|
||||
};
|
||||
}
|
||||
|
||||
export function Index() {
|
||||
const [timezone, setTimezone] = useState("N/A");
|
||||
const [clock, setClock] = useState("00:00:00");
|
||||
const [date, setDate] = useState("");
|
||||
const [currentScheduleIndex, setCurrentScheduleIndex] = useState(0);
|
||||
const [schedules, setSchedules] = useState<Schedule[]>([]);
|
||||
const [marqueeTexts, setMarqueeTexts] = useState<string[]>([]);
|
||||
const [grouppedSchedules, setGrouppedSchedules] = useState<
|
||||
{
|
||||
key: string;
|
||||
|
@ -51,15 +66,7 @@ export function Index() {
|
|||
importCompanyInfo
|
||||
);
|
||||
|
||||
const [data, setData] = useState<{
|
||||
harbor: {
|
||||
name: string;
|
||||
address: string;
|
||||
};
|
||||
embed_link: string[];
|
||||
marquee_text: string[];
|
||||
schedules: Schedule[];
|
||||
}>(importData);
|
||||
const [data, setData] = useState<AccountInfo | null>(null);
|
||||
|
||||
const chunkArray = (array: Schedule[], chunkSize: number) => {
|
||||
const result = [];
|
||||
|
@ -75,6 +82,7 @@ export function Index() {
|
|||
dayjs(x.departure_datetime).unix() - dayjs(y.departure_datetime).unix()
|
||||
);
|
||||
const scheduleChunks = chunkArray(sortDates, chunkSize);
|
||||
|
||||
const tempResult = [];
|
||||
|
||||
const todayDatetime = dayjs();
|
||||
|
@ -178,7 +186,7 @@ export function Index() {
|
|||
setDate(_date);
|
||||
}, 1000);
|
||||
|
||||
setGrouppedSchedules(groupDepartureDatetimes(data.schedules, 4));
|
||||
setGrouppedSchedules(groupDepartureDatetimes(schedules, 4));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -191,6 +199,64 @@ export function Index() {
|
|||
}
|
||||
}, [grouppedSchedules]);
|
||||
|
||||
|
||||
const checkAuth = async () => {
|
||||
const authToken = Cookies.get("ferinesia_schedule_board_token");
|
||||
try{
|
||||
const {data} = await createAxiosInstance({bearerToken: authToken}).get(endpoints.me);
|
||||
setData({...data, harbor: {name: data.data.harbor.name, address: data.data.harbor.address, code: data.data.harbor.code}});
|
||||
setMarqueeTexts(data.data.marquee_texts);
|
||||
}
|
||||
catch(err){
|
||||
if(err instanceof AxiosError){
|
||||
if(err.response?.data?.meta?.code == "E_UNAUTHENTICATED"){
|
||||
location.href = "/#/qr-login"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const fetchSchedules = async () => {
|
||||
const authToken = Cookies.get("ferinesia_schedule_board_token");
|
||||
const firstDatetime = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||
const secondDatetime = dayjs().add(7, 'day').format("YYYY-MM-DD HH:mm:ss");
|
||||
try{
|
||||
const {data} = await createAxiosInstance({bearerToken: authToken}).post(endpoints.schedule_entries, {
|
||||
start_departure_date: firstDatetime,
|
||||
end_departure_date: secondDatetime
|
||||
});
|
||||
|
||||
let tempSchedules: Schedule[] = [];
|
||||
for(const schedule of data.data.schedules){
|
||||
tempSchedules.push({
|
||||
departure_datetime: schedule.departure_datetime,
|
||||
dock_name: "Dek 1",
|
||||
destination: schedule.destination,
|
||||
status: ScheduleStatus.AVAILABLE,
|
||||
company_code: schedule.company_code,
|
||||
ship_name: schedule.ship_name
|
||||
});
|
||||
}
|
||||
|
||||
setGrouppedSchedules(groupDepartureDatetimes(tempSchedules, 4));
|
||||
}
|
||||
catch(err){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkAuth();
|
||||
// equivalent job using the "from" static method, providing parameters as an object
|
||||
CronJob.from({
|
||||
cronTime: '*/10 * * * *',
|
||||
onTick: fetchSchedules,
|
||||
start: true,
|
||||
timeZone: 'Asia/Jakarta',
|
||||
runOnInit: true
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="h-screen pl-4 pr-4 pt-4">
|
||||
|
@ -205,7 +271,7 @@ export function Index() {
|
|||
</div>
|
||||
<div className="col-span-4">
|
||||
<h3 className="text-5xl font-bold text-center text-[#2F95FA]">
|
||||
PELABUHAN BASTIONG
|
||||
PELABUHAN {data?.harbor.name ?? "N/A"} [{data?.harbor.code ?? "N/A"}]
|
||||
</h3>
|
||||
</div>
|
||||
<div className="col-span-4">
|
||||
|
@ -233,7 +299,7 @@ export function Index() {
|
|||
className="text-center text-4xl uppercase"
|
||||
style={{ width: "10%", letterSpacing: "3px" }}
|
||||
>
|
||||
JAM
|
||||
WAKTU BERANGKAT
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
|
@ -370,7 +436,7 @@ export function Index() {
|
|||
</div>
|
||||
<div className="whitespace-nowrap flex items-center overflow-x-hidden ml-1">
|
||||
<Marquee speed={100}>
|
||||
{data.marquee_text.map((x) => (
|
||||
{marqueeTexts.map((x) => (
|
||||
<h3 className="text-5xl ml-4 font-bold">{x}</h3>
|
||||
))}
|
||||
</Marquee>
|
||||
|
|
191
yarn.lock
191
yarn.lock
|
@ -562,6 +562,16 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
|
||||
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
|
||||
|
||||
"@types/js-cookie@^3.0.6":
|
||||
version "3.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-3.0.6.tgz#a04ca19e877687bd449f5ad37d33b104b71fdf95"
|
||||
integrity sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==
|
||||
|
||||
"@types/luxon@~3.4.0":
|
||||
version "3.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-3.4.2.tgz#e4fc7214a420173cea47739c33cdf10874694db7"
|
||||
integrity sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==
|
||||
|
||||
"@types/prop-types@*":
|
||||
version "15.7.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6"
|
||||
|
@ -746,6 +756,11 @@ argparse@^2.0.1:
|
|||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
||||
|
||||
autoprefixer@^10.4.20:
|
||||
version "10.4.20"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.20.tgz#5caec14d43976ef42e32dcb4bd62878e96be5b3b"
|
||||
|
@ -758,6 +773,15 @@ autoprefixer@^10.4.20:
|
|||
picocolors "^1.0.1"
|
||||
postcss-value-parser "^4.2.0"
|
||||
|
||||
axios@^1.8.4:
|
||||
version "1.8.4"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.4.tgz#78990bb4bc63d2cae072952d374835950a82f447"
|
||||
integrity sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==
|
||||
dependencies:
|
||||
follow-redirects "^1.15.6"
|
||||
form-data "^4.0.0"
|
||||
proxy-from-env "^1.1.0"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
|
@ -800,6 +824,14 @@ browserslist@^4.23.1, browserslist@^4.23.3:
|
|||
node-releases "^2.0.18"
|
||||
update-browserslist-db "^1.1.0"
|
||||
|
||||
call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
|
||||
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
function-bind "^1.1.2"
|
||||
|
||||
callsites@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||
|
@ -871,6 +903,13 @@ color-name@~1.1.4:
|
|||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
combined-stream@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@^4.0.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
|
||||
|
@ -886,6 +925,14 @@ convert-source-map@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
|
||||
integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
|
||||
|
||||
cron@^4.1.3:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/cron/-/cron-4.1.3.tgz#42661cebdf15483f90f63e799c9dbd33a298265c"
|
||||
integrity sha512-HETm5kgivcdfboOmBIzq0cfC9c5bRilWZ1p7PWwnOMmbWviwIU6mPgZbeqbj5i0AzNan6P68WDTDEDezhKjOng==
|
||||
dependencies:
|
||||
"@types/luxon" "~3.4.0"
|
||||
luxon "~3.6.0"
|
||||
|
||||
cross-spawn@^7.0.0, cross-spawn@^7.0.2:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
|
@ -922,6 +969,11 @@ deep-is@^0.1.3:
|
|||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||
|
||||
didyoumean@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
|
||||
|
@ -932,6 +984,15 @@ dlv@^1.1.3:
|
|||
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
|
||||
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
|
||||
|
||||
dunder-proto@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
|
||||
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
|
||||
dependencies:
|
||||
call-bind-apply-helpers "^1.0.1"
|
||||
es-errors "^1.3.0"
|
||||
gopd "^1.2.0"
|
||||
|
||||
eastasianwidth@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
|
||||
|
@ -952,6 +1013,33 @@ emoji-regex@^9.2.2:
|
|||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
|
||||
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
|
||||
|
||||
es-define-property@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
|
||||
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
|
||||
|
||||
es-errors@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
|
||||
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
|
||||
|
||||
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
|
||||
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
|
||||
es-set-tostringtag@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d"
|
||||
integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
get-intrinsic "^1.2.6"
|
||||
has-tostringtag "^1.0.2"
|
||||
hasown "^2.0.2"
|
||||
|
||||
esbuild@^0.21.3:
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d"
|
||||
|
@ -1165,6 +1253,11 @@ flatted@^3.2.9:
|
|||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a"
|
||||
integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==
|
||||
|
||||
follow-redirects@^1.15.6:
|
||||
version "1.15.9"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1"
|
||||
integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
|
||||
|
||||
foreground-child@^3.1.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77"
|
||||
|
@ -1173,6 +1266,16 @@ foreground-child@^3.1.0:
|
|||
cross-spawn "^7.0.0"
|
||||
signal-exit "^4.0.1"
|
||||
|
||||
form-data@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.2.tgz#35cabbdd30c3ce73deb2c42d3c8d3ed9ca51794c"
|
||||
integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.8"
|
||||
es-set-tostringtag "^2.1.0"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fraction.js@^4.3.7:
|
||||
version "4.3.7"
|
||||
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
|
||||
|
@ -1193,6 +1296,30 @@ gensync@^1.0.0-beta.2:
|
|||
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
|
||||
|
||||
get-intrinsic@^1.2.6:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01"
|
||||
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
|
||||
dependencies:
|
||||
call-bind-apply-helpers "^1.0.2"
|
||||
es-define-property "^1.0.1"
|
||||
es-errors "^1.3.0"
|
||||
es-object-atoms "^1.1.1"
|
||||
function-bind "^1.1.2"
|
||||
get-proto "^1.0.1"
|
||||
gopd "^1.2.0"
|
||||
has-symbols "^1.1.0"
|
||||
hasown "^2.0.2"
|
||||
math-intrinsics "^1.1.0"
|
||||
|
||||
get-proto@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
|
||||
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
|
||||
dependencies:
|
||||
dunder-proto "^1.0.1"
|
||||
es-object-atoms "^1.0.0"
|
||||
|
||||
glob-parent@^5.1.2, glob-parent@~5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
|
@ -1234,6 +1361,11 @@ globals@^15.9.0:
|
|||
resolved "https://registry.yarnpkg.com/globals/-/globals-15.9.0.tgz#e9de01771091ffbc37db5714dab484f9f69ff399"
|
||||
integrity sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==
|
||||
|
||||
gopd@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
|
||||
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
|
||||
|
||||
graphemer@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
|
||||
|
@ -1249,6 +1381,18 @@ has-flag@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
has-symbols@^1.0.3, has-symbols@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
|
||||
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
|
||||
|
||||
has-tostringtag@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
|
||||
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
|
||||
dependencies:
|
||||
has-symbols "^1.0.3"
|
||||
|
||||
hasown@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
|
||||
|
@ -1334,6 +1478,11 @@ jiti@^1.21.0:
|
|||
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268"
|
||||
integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==
|
||||
|
||||
js-cookie@^3.0.5:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc"
|
||||
integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
|
@ -1432,6 +1581,16 @@ lru-cache@^5.1.1:
|
|||
dependencies:
|
||||
yallist "^3.0.2"
|
||||
|
||||
luxon@~3.6.0:
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.6.1.tgz#d283ffc4c0076cb0db7885ec6da1c49ba97e47b0"
|
||||
integrity sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==
|
||||
|
||||
math-intrinsics@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
|
||||
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
|
||||
|
||||
merge2@^1.3.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||
|
@ -1445,6 +1604,18 @@ micromatch@^4.0.4, micromatch@^4.0.5:
|
|||
braces "^3.0.3"
|
||||
picomatch "^2.3.1"
|
||||
|
||||
mime-db@1.52.0:
|
||||
version "1.52.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||
|
||||
mime-types@^2.1.12:
|
||||
version "2.1.35"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
||||
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
||||
dependencies:
|
||||
mime-db "1.52.0"
|
||||
|
||||
minimatch@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
|
@ -1659,7 +1830,7 @@ prelude-ls@^1.2.1:
|
|||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
||||
|
||||
prop-types@^15.7.2:
|
||||
prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
|
@ -1668,11 +1839,21 @@ prop-types@^15.7.2:
|
|||
object-assign "^4.1.1"
|
||||
react-is "^16.13.1"
|
||||
|
||||
proxy-from-env@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
||||
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
|
||||
|
||||
qr.js@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f"
|
||||
integrity sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==
|
||||
|
||||
queue-microtask@^1.2.2:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||
|
@ -1716,6 +1897,14 @@ react-is@^16.13.1:
|
|||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
|
||||
react-qr-code@^2.0.15:
|
||||
version "2.0.15"
|
||||
resolved "https://registry.yarnpkg.com/react-qr-code/-/react-qr-code-2.0.15.tgz#fbfc12952c504bcd64275647e9d1ea63251742ce"
|
||||
integrity sha512-MkZcjEXqVKqXEIMVE0mbcGgDpkfSdd8zhuzXEl9QzYeNcw8Hq2oVIzDLWuZN2PQBwM5PWjc2S31K8Q1UbcFMfw==
|
||||
dependencies:
|
||||
prop-types "^15.8.1"
|
||||
qr.js "0.0.0"
|
||||
|
||||
react-refresh@^0.14.2:
|
||||
version "0.14.2"
|
||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9"
|
||||
|
|
Loading…
Reference in New Issue