diff --git a/app/data/pinning.ts b/app/data/pinning.ts new file mode 100644 index 0000000..80d9540 --- /dev/null +++ b/app/data/pinning.ts @@ -0,0 +1,55 @@ +interface PinningStatus { + id: string; + progress: number; + status: 'inprogress' | 'completed' | 'stale'; +} + +// biome-ignore lint/complexity/noStaticOnlyClass: +class PinningProcess { + private static instances: Map = new Map(); + + static async pin(id: string): Promise<{ success: boolean; message: string }> { + if (PinningProcess.instances.has(id)) { + return { success: false, message: "ID is already being processed" }; + } + + const pinningStatus: PinningStatus = { id, progress: 0, status: 'inprogress' }; + PinningProcess.instances.set(id, pinningStatus); + + // Simulate async progress + (async () => { + for (let progress = 1; progress <= 100; progress++) { + await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * (500 - 100 + 1)) + 100)); // Simulate time passing with random duration between 100 and 500 + pinningStatus.progress = progress; + if (progress === 100) { + pinningStatus.status = 'completed'; + } + } + })(); + + return { success: true, message: "Pinning process started" }; + } + + static *pollProgress(id: string): Generator { + let status = PinningProcess.instances.get(id); + while (status && status.status !== 'completed') { + yield status; + status = PinningProcess.instances.get(id); + } + yield status ?? null; // Yield the final status, could be null if ID doesn't exist + } +} + +// Example usage: +// (async () => { +// const { success, message } = await PinningProcess.pin("123"); +// console.log(message); +// if (success) { +// const progressGenerator = PinningProcess.pollProgress("123"); +// let result = progressGenerator.next(); +// while (!result.done) { +// console.log(result.value); // Log the progress +// result = progressGenerator.next(); +// } +// } +// })(); diff --git a/app/routes/account.tsx b/app/routes/account.tsx index b8d32f7..41a4717 100644 --- a/app/routes/account.tsx +++ b/app/routes/account.tsx @@ -1,12 +1,23 @@ import { getFormProps, useForm } from "@conform-to/react"; import { getZodConstraint, parseWithZod } from "@conform-to/zod"; -import { BaseKey, useGetIdentity, useUpdate, useUpdatePassword } from "@refinedev/core"; +import { + BaseKey, + useGetIdentity, + useUpdate, + useUpdatePassword, +} from "@refinedev/core"; import { useState } from "react"; import { z } from "zod"; import { Field } from "~/components/forms"; import { GeneralLayout } from "~/components/general-layout"; import { AddIcon, CloudIcon, CrownIcon } from "~/components/icons"; -import { ManagementCard, ManagementCardAvatar, ManagementCardContent, ManagementCardFooter, ManagementCardTitle } from "~/components/management-card"; +import { + ManagementCard, + ManagementCardAvatar, + ManagementCardContent, + ManagementCardFooter, + ManagementCardTitle, +} from "~/components/management-card"; import { Button } from "~/components/ui/button"; import { Dialog, @@ -51,10 +62,12 @@ export default function MyAccount() { Email Address - {identity?.email} + {identity?.email} - @@ -63,8 +76,8 @@ export default function MyAccount() { Account Type - Lite Premium Account - + Lite Premium Account + @@ -91,35 +106,27 @@ export default function MyAccount() { Two-Factor Authentication - Improve security by enabling 2FA. + Improve security by enabling 2FA. - - - Backup Key - - Never share this code with anyone. - - - - -

More

Invite a Friend - Get 1 GB per friend invited for free (max 5 GB). + + Get 1 GB per friend invited for free (max 5 GB). + - @@ -127,7 +134,9 @@ export default function MyAccount() { Read our Resources - Navigate helpful articles or get assistance. + + Navigate helpful articles or get assistance. +