-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into feature/animated-headline
- Loading branch information
Showing
53 changed files
with
1,493 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,3 +25,5 @@ CRYPTOMUS_ID="id" | |
CRYPTOMUS_API_KEY="key" | ||
|
||
CARDLINK_API_KEY="key" | ||
|
||
ADMITAD_POSTBACK_KEY="key" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { PageSection } from "@/components/page-section" | ||
import { getScopedI18n } from "@/shared/locales/server" | ||
|
||
export default async function NotFound() { | ||
const t = await getScopedI18n("not_found") | ||
|
||
return ( | ||
<PageSection className="flex flex-col items-center"> | ||
<h1 className="text-4xl font-bold mb-8 text-center">{t("404")}</h1> | ||
<h3 className="text-xl mb-8 text-center">{t("404_sub")}</h3> | ||
<form | ||
action="https://www.google.com/search" | ||
method="get" | ||
className="flex flex-col items-center" | ||
> | ||
<input | ||
type="text" | ||
name="q" | ||
placeholder={t("search_site")} | ||
required | ||
className="border p-3 mb-4 w-80 rounded-lg shadow-md focus:outline-none focus:ring-2 focus:ring-blue-500" | ||
/> | ||
<input type="hidden" name="sitesearch" value="frkn.org" /> | ||
<button | ||
type="submit" | ||
className="bg-blue-600 hover:bg-blue-500 text-white px-5 py-3 rounded" | ||
> | ||
{t("search")} | ||
</button> | ||
</form> | ||
</PageSection> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { Skeleton } from "@/components/ui/skeleton" | ||
|
||
export default function Loading() { | ||
return ( | ||
<div> | ||
<div className="grid grid-rows-1 lg:grid-cols-[1fr_auto] max-w-6xl w-full mx-auto px-4 gap-6"> | ||
<div className="flex flex-col lg:flex-row items-center justify-center gap-8 p-8"> | ||
<Skeleton className="w-full h-16 mt-2" /> | ||
<Skeleton className="w-full h-16 mt-2" /> | ||
</div> | ||
</div> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,291 @@ | ||
"use client" | ||
import { QrModal } from "@/components/qr-modal" | ||
import { SubLinkInput } from "@/components/sub-link-input" | ||
import { Button } from "@/components/ui/button" | ||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardHeader, | ||
CardTitle, | ||
} from "@/components/ui/card" | ||
import { | ||
Table, | ||
TableBody, | ||
TableCell, | ||
TableHead, | ||
TableHeader, | ||
TableRow, | ||
} from "@/components/ui/table" | ||
import { | ||
Tooltip, | ||
TooltipContent, | ||
TooltipTrigger, | ||
} from "@/components/ui/tooltip" | ||
import { formatBytes } from "@/shared/format/bytes" | ||
import { formatExpire, formatStrategy } from "@/shared/format/strategy" | ||
import { useCurrentLocale, useScopedI18n } from "@/shared/locales/client" | ||
import { trpc } from "@/shared/trpc" | ||
import { Copy, LayoutGrid, Loader2, QrCode } from "lucide-react" | ||
import Link from "next/link" | ||
import { useState } from "react" | ||
import { | ||
AiFillAndroid, | ||
AiFillApple, | ||
AiFillWindows, | ||
AiOutlineAndroid, | ||
AiOutlineApple, | ||
AiOutlineLinux, | ||
AiOutlineMacCommand, | ||
AiOutlineWindows, | ||
} from "react-icons/ai" | ||
|
||
export function Main() { | ||
const t = useScopedI18n("app.dashboard") | ||
const locale = useCurrentLocale() | ||
const [isModalOpen, setModalOpen] = useState(false) | ||
const [qr, setQr] = useState("") | ||
const showQr = (data: string) => { | ||
setQr(data) | ||
setModalOpen(true) | ||
} | ||
const { data, isLoading, isSuccess, refetch } = trpc.xray.get.useQuery( | ||
undefined, | ||
{ | ||
refetchOnWindowFocus: false, | ||
}, | ||
) | ||
|
||
if (isLoading) { | ||
return ( | ||
<div className="flex flex-col lg:flex-row items-center justify-center gap-8 p-8"> | ||
<Loader2 className="ml-4 h-6 w-6 animate-spin" /> | ||
</div> | ||
) | ||
} | ||
|
||
if (!data || !isSuccess) { | ||
return ( | ||
<div className="text-center mt-4"> | ||
<p>{t("error_message")}</p> | ||
<div className="flex justify-center mt-2"> | ||
<button | ||
onClick={() => refetch()} | ||
disabled={isLoading} | ||
className="px-4 py-2 bg-blue-500 text-white rounded flex items-center justify-center" | ||
> | ||
{isLoading && <Loader2 className="mr-2 h-6 w-6 animate-spin" />} | ||
{t("reload_button")} | ||
</button> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
return ( | ||
<Card> | ||
<CardHeader> | ||
<CardTitle className="text-2xl/8 font-semibold text-foreground sm:text-xl/8"> | ||
{t("title")} | ||
</CardTitle> | ||
<CardDescription> | ||
{t("status")}: {data.status} | ||
<br /> | ||
{t("traffic_limit")}: {formatBytes(data.limit)}{" "} | ||
{formatStrategy(data.limit_reset_strategy, locale)} | ||
{formatExpire(data.expire, locale)} | ||
<br /> | ||
{t("used_traffic")}: {formatBytes(data.used_traffic)} | ||
</CardDescription> | ||
</CardHeader> | ||
|
||
<CardContent className="space-y-8"> | ||
<div> | ||
<CardTitle className="mb-2">XRay</CardTitle> | ||
<CardDescription className="text-balance mb-2"> | ||
{t("xrayDescription")} | ||
</CardDescription> | ||
<div className="flex flex-wrap gap-2 mb-2"> | ||
<Button size="sm" asChild> | ||
<Link | ||
href="https://apps.microsoft.com/detail/9pdfnl3qv2s5" | ||
target="_blank" | ||
> | ||
<AiFillWindows className="mr-1" /> | ||
Windows | ||
</Link> | ||
</Button> | ||
<Button size="sm" asChild> | ||
<Link | ||
href="https://apps.apple.com/ru/app/foxray/id6448898396" | ||
target="_blank" | ||
> | ||
<AiFillApple className="mr-1" /> | ||
iOS & MacOS | ||
</Link> | ||
</Button> | ||
<Button size="sm" asChild> | ||
<Link | ||
href="https://play.google.com/store/apps/details?id=app.hiddify.com" | ||
target="_blank" | ||
> | ||
<AiFillAndroid className="mr-1" /> | ||
Android | ||
</Link> | ||
</Button> | ||
</div> | ||
|
||
<Table> | ||
<TableBody> | ||
<TableRow className="bg-muted/50"> | ||
<TableCell className="font-medium"> | ||
<SubLinkInput value={data.subscription_url} /> | ||
</TableCell> | ||
<TableCell> | ||
<div className="flex gap-2"> | ||
<Tooltip> | ||
<TooltipTrigger asChild> | ||
<Button | ||
aria-label="Copy Config" | ||
size="sm" | ||
onClick={() => { | ||
navigator.clipboard.writeText(data.subscription_url) | ||
}} | ||
> | ||
<Copy className="h-4 w-4 md:mr-2" /> | ||
<span className="hidden md:block">{t("copy")}</span> | ||
</Button> | ||
</TooltipTrigger> | ||
<TooltipContent className="max-w-56 break-words drop-shadow-md"> | ||
{data.subscription_url} | ||
</TooltipContent> | ||
</Tooltip> | ||
<Button | ||
aria-label="Show QR Code" | ||
onClick={() => showQr(data.subscription_url)} | ||
size="sm" | ||
> | ||
<QrCode className="h-4 w-4 md:mr-2" /> | ||
<span className="hidden md:block">{t("showQr")}</span> | ||
</Button> | ||
</div> | ||
</TableCell> | ||
</TableRow> | ||
</TableBody> | ||
</Table> | ||
</div> | ||
<div> | ||
<CardTitle className="mb-2">Shadowsocks</CardTitle> | ||
<CardDescription className="text-balance mb-2"> | ||
{t("shadowsocksDescription")} | ||
</CardDescription> | ||
<div className="flex flex-wrap gap-2 mb-2"> | ||
<Button size="sm" asChild> | ||
<Link | ||
href="https://s3.amazonaws.com/outline-releases/client/windows/stable/Outline-Client.exe" | ||
target="_blank" | ||
> | ||
<AiOutlineWindows className="mr-1" /> | ||
Windows | ||
</Link> | ||
</Button> | ||
<Button size="sm" asChild> | ||
<Link | ||
href="https://itunes.apple.com/us/app/outline-app/id1356178125" | ||
target="_blank" | ||
> | ||
<AiOutlineMacCommand className="mr-1" /> | ||
MacOS | ||
</Link> | ||
</Button> | ||
<Button size="sm" asChild> | ||
<Link | ||
href="https://s3.amazonaws.com/outline-releases/client/linux/stable/Outline-Client.AppImage" | ||
target="_blank" | ||
> | ||
<AiOutlineLinux className="mr-1" /> | ||
Linux | ||
</Link> | ||
</Button> | ||
<Button size="sm" asChild> | ||
<Link | ||
href="https://itunes.apple.com/us/app/outline-app/id1356177741" | ||
target="_blank" | ||
> | ||
<AiOutlineApple className="mr-1" /> | ||
iOS | ||
</Link> | ||
</Button> | ||
<Button size="sm" asChild> | ||
<Link | ||
href="https://play.google.com/store/apps/details?id=org.outline.android.client" | ||
target="_blank" | ||
> | ||
<AiOutlineAndroid className="mr-1" /> | ||
Android | ||
</Link> | ||
</Button> | ||
</div> | ||
|
||
<Table> | ||
<TableHeader> | ||
<TableRow> | ||
<TableHead>{t("country")}</TableHead> | ||
</TableRow> | ||
</TableHeader> | ||
<TableBody> | ||
{data.ss_links.map(({ link, country }) => ( | ||
<TableRow key={link}> | ||
<TableCell className="font-medium">{country}</TableCell> | ||
<TableCell> | ||
<div className="flex gap-2"> | ||
<Button size="sm" asChild> | ||
<Link href={link}> | ||
<LayoutGrid className="h-4 w-4 md:mr-2" /> | ||
<span className="hidden md:block"> | ||
{t("openInApp")} | ||
</span> | ||
</Link> | ||
</Button> | ||
<Tooltip> | ||
<TooltipTrigger asChild> | ||
<Button | ||
aria-label="Copy Config" | ||
size="sm" | ||
onClick={() => { | ||
navigator.clipboard.writeText(link) | ||
}} | ||
> | ||
<Copy className="h-4 w-4 md:mr-2" /> | ||
<span className="hidden md:block">{t("copy")}</span> | ||
</Button> | ||
</TooltipTrigger> | ||
<TooltipContent className="max-w-56 break-words drop-shadow-md"> | ||
{link} | ||
</TooltipContent> | ||
</Tooltip> | ||
<Button | ||
aria-label="Show QR Code" | ||
onClick={() => showQr(link)} | ||
size="sm" | ||
> | ||
<QrCode className="h-4 w-4 md:mr-2" /> | ||
<span className="hidden md:block">{t("showQr")}</span> | ||
</Button> | ||
</div> | ||
</TableCell> | ||
</TableRow> | ||
))} | ||
</TableBody> | ||
</Table> | ||
</div> | ||
</CardContent> | ||
|
||
<QrModal | ||
isOpen={isModalOpen} | ||
close={() => setModalOpen(false)} | ||
data={qr} | ||
/> | ||
</Card> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { Main } from "./main" | ||
|
||
export default function Page() { | ||
return <Main /> | ||
} |
Oops, something went wrong.