Files
NwaifuMiniApp/src/app/page.tsx

124 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { Block } from "@/components/Block";
import { Carousel } from "@/components/Carousel/Carousel";
import { Loader } from "@/components/Loader";
import { Page } from "@/components/Page";
import { cn } from "@/utils/cn";
import { useRawInitData } from "@telegram-apps/sdk-react";
import { ChevronLeft, ChevronRight, ClipboardList } from "lucide-react";
import { QRCodeSVG } from "qrcode.react";
import { useEffect, useState } from "react";
import { getUrl } from "./actions";
interface ProxySubData {
url: string;
expiryTime: number;
}
type ProxySubArray = ProxySubData[];
export default function Home() {
const [proxyData, setProxyData] = useState<ProxySubArray>([]);
const [chosen, setChosen] = useState(0);
const [isLoading, setIsLoading] = useState(true);
const [notFound, setNotFound] = useState(false);
const initData = useRawInitData();
const onCopyClick = async (url: string) => {
if (!proxyData.length) return;
await navigator.clipboard.writeText(url);
setIsCopied(true);
setTimeout(() => {
setIsCopied(false);
}, 2000);
};
const [isCopied, setIsCopied] = useState(false);
useEffect(() => {
const fetchData = async () => {
try {
const data = await getUrl(initData);
setProxyData(data);
setIsLoading(false);
} catch (e) {
console.error(e);
setNotFound(true);
setIsLoading(false);
}
};
fetchData();
}, [initData]);
if (isLoading) return <Loader />;
if (notFound) {
return (
<Page back={false}>
<main className="absolute bottom-0 left-0 flex w-full flex-col items-center gap-3 px-2.5 py-3.5 text-[var(--tg-theme-text-color)]">
<Block name="Ссылка">Ссылка не найдена</Block>
</main>
</Page>
);
}
return (
<Page back={false}>
<header className="flex h-12 w-full flex-col items-center justify-center bg-[var(--tg-theme-header-bg-color)]">
<span className="text-xl font-semibold text-[var(--tg-theme-text-color)]">Nwaifu Proxy</span>
</header>
<main className="absolute bottom-0 left-0 flex w-full flex-col items-center gap-3 px-2.5 py-3.5 text-[var(--tg-theme-text-color)]">
{proxyData.length && (
<>
<Block name="Ссылка">
<div className="flex w-full flex-row items-center justify-between">
<ChevronLeft onClick={() => setChosen(chosen - 1 < 0 ? proxyData.length - 1 : chosen - 1)} />
<Carousel loop>
{proxyData.map((item, index) => (
<div
className="relative flex size-52 flex-[0_0_100%] flex-col items-center justify-center rounded-md bg-white"
onClick={() => onCopyClick(item.url)}
key={index}
>
<div
className={cn(
"absolute top-0 left-0 flex h-full w-full flex-col items-center justify-center rounded-md bg-[var(--tg-theme-button-color)] opacity-0 transition-opacity",
isCopied && "opacity-95"
)}
>
<span className="flex flex-row text-lg font-semibold text-[var(--tg-theme-button-text-color)]">
Скопировано
<ClipboardList className="text-[var(--tg-theme-button-text-color)]" />
</span>
</div>
<QRCodeSVG value={item.url} className="size-48" />
</div>
))}
</Carousel>
<ChevronRight onClick={() => setChosen(chosen + 1 > proxyData.length - 1 ? 0 : chosen + 1)} />
</div>
<span className="text-center text-sm font-semibold">Нажмите на QR, чтобы скопировать!</span>
</Block>
<Block name="Подписка">
<div className="flex flex-col items-center gap-0.5">
<span>Статус:</span>
<span>
{proxyData[chosen].expiryTime > Date.now() || proxyData[chosen].expiryTime === 0
? "Активна"
: "Не Активна"}
</span>
</div>
<div className="flex flex-col items-center gap-0.5">
<span>Активна до:</span>
<span>
{proxyData[chosen].expiryTime === 0
? "Всегда"
: proxyData[chosen].expiryTime > Date.now()
? new Date(proxyData[chosen].expiryTime).toLocaleString("ru-RU")
: "Не Активна"}
</span>
</div>
</Block>
</>
)}
</main>
</Page>
);
}