mirror of
https://gitea.tendokyu.moe/ppc/amnet.git
synced 2026-10-02 03:37:58 +03:00
handle */add routes
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import {z} from "zod";
|
||||
import React from "react";
|
||||
import React, {useEffect} from "react";
|
||||
import {Check, Plus, X} from "lucide-react";
|
||||
import {FormProvider, useForm} from "react-hook-form";
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
} from "@/components/ui/drawer";
|
||||
import {useLiveQuery} from "dexie-react-hooks";
|
||||
import {cn} from "@/lib/utils.ts";
|
||||
import {useLocation} from "react-router-dom";
|
||||
|
||||
const schema = z.object({
|
||||
name: z.string().min(1, {
|
||||
@@ -118,11 +119,18 @@ function AimeCardCreationForm(props: { callback?: () => void }) {
|
||||
}
|
||||
|
||||
export function CardCreationDialog(props: { className?: string }) {
|
||||
const location = useLocation();
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
const cardCount = useLiveQuery(() => db.cards.count());
|
||||
const isDesktop = useMediaQuery("(min-width: 768px)");
|
||||
|
||||
useEffect(() => {
|
||||
if (location.pathname === "/cards/add") {
|
||||
setOpen(true);
|
||||
}
|
||||
}, [location]);
|
||||
|
||||
const disableCreation = (cardCount !== undefined && cardCount >= CARD_LIMIT) ?? false;
|
||||
const creationComponent = (
|
||||
<Button className={cn('bg-blue-500', props.className)}>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {z} from "zod";
|
||||
import TimeAgo from "react-timeago";
|
||||
import React, {useState} from "react";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {useForm} from "react-hook-form";
|
||||
import {useNavigate} from 'react-router-dom';
|
||||
import {useLocation, useNavigate} from 'react-router-dom';
|
||||
import {useLiveQuery} from "dexie-react-hooks";
|
||||
import {zodResolver} from "@hookform/resolvers/zod";
|
||||
import {
|
||||
@@ -49,16 +49,18 @@ function ServerList(props: { servers: AimeServer[] | undefined }) {
|
||||
if (!props.servers.length) {
|
||||
return (
|
||||
<>
|
||||
<ServerAddForm/>
|
||||
<div className="flex flex-col gap-2 items-center text-gray-500 pt-6 pb-5">
|
||||
<Earth className="h-8 w-8"/>
|
||||
<span className="text-center">No servers found. Add one below!</span>
|
||||
<span className="text-center">No servers found. Add one above!</span>
|
||||
</div>
|
||||
<ServerAddForm/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (<>
|
||||
<ServerAddForm/>
|
||||
|
||||
{props.servers.map(s =>
|
||||
<ContextMenu key={s.id}>
|
||||
<ContextMenuTrigger>
|
||||
@@ -85,13 +87,13 @@ function ServerList(props: { servers: AimeServer[] | undefined }) {
|
||||
</ContextMenuItem>
|
||||
</ContextMenuContent>
|
||||
</ContextMenu>)}
|
||||
|
||||
<ServerAddForm/>
|
||||
</>);
|
||||
}
|
||||
|
||||
function ServerAddForm() {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const form = useForm<z.infer<typeof serverAdditionSchema>>({
|
||||
resolver: zodResolver(serverAdditionSchema),
|
||||
defaultValues: {
|
||||
@@ -102,6 +104,33 @@ function ServerAddForm() {
|
||||
const [showHttpsWarning, setHttpsWarning] = useState(false);
|
||||
const [blockSubmit, setBlockSubmit] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (location.pathname != "/servers/add") {
|
||||
return;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const searchParams = new URLSearchParams(location.search);
|
||||
let address = searchParams.get("address");
|
||||
|
||||
if (!address) {
|
||||
return;
|
||||
}
|
||||
|
||||
address = decodeURIComponent(address);
|
||||
const server = await db.servers.filter(x => x.address === address).first();
|
||||
|
||||
if (server) {
|
||||
navigate(`/servers/${server.id}`);
|
||||
} else {
|
||||
validateAddress(address);
|
||||
|
||||
form.setValue("address", address);
|
||||
form.setFocus("address");
|
||||
}
|
||||
})();
|
||||
}, [location, navigate, form]);
|
||||
|
||||
async function onSubmit(values: z.infer<typeof serverAdditionSchema>) {
|
||||
const existingServer = await db.servers
|
||||
.where("address")
|
||||
@@ -130,28 +159,31 @@ function ServerAddForm() {
|
||||
}
|
||||
|
||||
function handleAddressChange(event: React.ChangeEvent<HTMLInputElement>, callback: (value: React.ChangeEvent<HTMLInputElement>) => void) {
|
||||
validateAddress(event.target.value);
|
||||
callback(event);
|
||||
}
|
||||
|
||||
function validateAddress(address: string) {
|
||||
try {
|
||||
const address = new URL(event.target.value);
|
||||
const url = new URL(address);
|
||||
|
||||
setBlockSubmit(false);
|
||||
setHttpsWarning(address.protocol !== "http:");
|
||||
setHttpsWarning(url.protocol !== "http:");
|
||||
} catch {
|
||||
setBlockSubmit(true);
|
||||
setHttpsWarning(false);
|
||||
}
|
||||
|
||||
callback(event);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{showHttpsWarning && (<>
|
||||
<div></div>
|
||||
<Alert variant="blank" className="text-yellow-500 border-yellow-500">
|
||||
<ShieldAlert className="h-5 w-5 text-yellow-500"/>
|
||||
<Alert variant="blank" className="text-orange-500 border-orange-500">
|
||||
<ShieldAlert className="h-5 w-5 text-orange-500"/>
|
||||
<AlertTitle>HTTPS Warning</AlertTitle>
|
||||
<AlertDescription>
|
||||
AimeNet doesn't support HTTPS out-the-box.
|
||||
AMNet doesn't support HTTPS out-the-box.
|
||||
If you're using HTTPS, ensure a reverse-proxy or
|
||||
<a target="_blank"
|
||||
className="underline ml-1"
|
||||
@@ -194,7 +226,7 @@ function ServerListing() {
|
||||
|
||||
return (
|
||||
<main className="flex flex-col gap-5 container min-h-screen py-10">
|
||||
<AMHeader title="AimeNet">
|
||||
<AMHeader title="Servers">
|
||||
<Button variant="ghost" size={"default"} onClick={() => navigate('/cards')}>
|
||||
<WalletCards className="h-4 w-4 sm:mr-2"/>
|
||||
<span className="hidden sm:block">Manage Cards</span>
|
||||
|
||||
Reference in New Issue
Block a user