38 lines
3.6 KiB
TypeScript
38 lines
3.6 KiB
TypeScript
"use client";
|
|
|
|
import { useMemo, useState } from "react";
|
|
import { ImportIcon } from "lucide-react";
|
|
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
|
|
import { Field, FieldDescription, FieldError, FieldGroup, FieldLabel } from "@/components/ui/field";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Textarea } from "@/components/ui/textarea";
|
|
import { importGcsimConfig } from "@/lib/translator/import";
|
|
import type { Catalog, Team } from "@/lib/translator/types";
|
|
|
|
export function ImportGcsimDialog({ catalog, disabled, onImport }: { catalog: Catalog; disabled: boolean; onImport: (team: Team) => void }) {
|
|
const [open, setOpen] = useState(false);
|
|
const [input, setInput] = useState("");
|
|
const [name, setName] = useState("Imported team");
|
|
const preview = useMemo(() => input.trim() ? importGcsimConfig(input, catalog, name) : undefined, [input, catalog, name]);
|
|
const error = preview?.error;
|
|
return <Dialog open={open} onOpenChange={setOpen}>
|
|
<DialogTrigger render={<Button variant="outline" className="self-start" disabled={disabled} />}><ImportIcon data-icon="inline-start" />Import from gcsim</DialogTrigger>
|
|
<DialogContent className="max-h-[90dvh] overflow-y-auto sm:max-w-2xl">
|
|
<DialogHeader><DialogTitle>Import from gcsim</DialogTitle><DialogDescription>Paste character settings, artifact stats, and rotation script. Import creates a new team.</DialogDescription></DialogHeader>
|
|
<FieldGroup>
|
|
<Field><FieldLabel htmlFor="gcsim-import-name">Team name</FieldLabel><Input id="gcsim-import-name" value={name} maxLength={60} onChange={(event) => setName(event.target.value)} /></Field>
|
|
<Field data-invalid={Boolean(error)}><FieldLabel htmlFor="gcsim-import-input">Gcsim config</FieldLabel><Textarea id="gcsim-import-input" className="min-h-64" value={input} maxLength={100000} onChange={(event) => setInput(event.target.value)} placeholder={'bennett char lvl=90/90 cons=0 talent=9,9,9;\nbennett add weapon="favoniussword" refine=1 lvl=90/90;\nbennett add set="noblesseoblige" count=4;\nbennett add stats hp=4780 atk=311 er=0.518;\n\nactive bennett;\nbennett skill, burst;'} aria-invalid={Boolean(error)} aria-describedby={`gcsim-import-help${error ? " gcsim-import-error" : ""}`} /><FieldDescription id="gcsim-import-help">Exact artifact values are preserved. Loops and action parameters stay as gcsim script. Character and equipment keys must exist in the catalog.</FieldDescription>{error && <FieldError id="gcsim-import-error">{error}</FieldError>}</Field>
|
|
{preview?.team && <Alert><AlertTitle>Ready to import</AlertTitle><AlertDescription>{preview.team.builds.map((build) => build.characterName).join(", ")} · {preview.team.builds.length} character{preview.team.builds.length === 1 ? "" : "s"} · {preview.team.rotation?.enabled ? "Rotation included" : "No rotation"}</AlertDescription></Alert>}
|
|
{preview?.warnings?.map((warning) => <Alert key={warning}><AlertTitle>Import note</AlertTitle><AlertDescription>{warning}</AlertDescription></Alert>)}
|
|
</FieldGroup>
|
|
<DialogFooter><DialogClose render={<Button variant="outline" />}>Cancel</DialogClose><Button disabled={disabled || !preview?.team} onClick={() => {
|
|
if (!preview?.team || disabled) return;
|
|
onImport(preview.team);
|
|
setOpen(false); setInput(""); setName("Imported team");
|
|
}}>Import team</Button></DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>;
|
|
}
|