Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

```env
NEXT_PUBLIC_BACKEND_BASE_URL=
APP_REDIRECT_URL=
AUTH_SECRET=
```

## Development
Expand Down
87 changes: 56 additions & 31 deletions app/(admin)/(question-management)/database/_components/create.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { buttonVariants } from "@/components/ui/button";
import { ConfirmationDialog } from "@/components/ui/confirmation-dialog";
import {
Dialog,
DialogContent,
Expand All @@ -9,35 +10,66 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { useDialogCloseConfirmation } from "@/hooks/use-dialog-close-confirmation";
import { useMutation } from "@apollo/client/react";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { toast } from "sonner";
import { DATABASE_CREATE_MUTATION } from "./mutation";
import { DATABASES_TABLE_QUERY } from "./query";
import { UpdateDatabaseForm, type UpdateDatabaseFormData } from "./update-form";
import { UpdateDatabaseForm } from "./update-form";

export function CreateDatabaseTrigger() {
const router = useRouter();
const [open, setOpen] = useState(false);
const [isFormDirty, setIsFormDirty] = useState(false);

const {
showConfirmation,
handleDialogOpenChange,
handleConfirmClose,
handleCancelClose,
} = useDialogCloseConfirmation({
isDirty: isFormDirty,
setOpen,
onConfirmedClose: () => {
setIsFormDirty(false);
},
});

const handleFormStateChange = (isDirty: boolean) => {
setIsFormDirty(isDirty);
};

const handleCompleted = () => {
setIsFormDirty(false);
setOpen(false);
};

return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger className={buttonVariants()}>新增資料庫</DialogTrigger>
<CreateDatabaseDialogContent
onCompleted={() => {
setOpen(false);
router.refresh();
}}
<>
<Dialog open={open} onOpenChange={handleDialogOpenChange}>
<DialogTrigger className={buttonVariants()}>新增資料庫</DialogTrigger>
<CreateDatabaseDialogContent
onCompleted={handleCompleted}
onFormStateChange={handleFormStateChange}
/>
</Dialog>

<ConfirmationDialog
open={showConfirmation}
onOpenChange={() => {}}
onConfirm={handleConfirmClose}
onCancel={handleCancelClose}
/>
</Dialog>
</>
);
}

function CreateDatabaseDialogContent({
onCompleted,
onFormStateChange,
}: {
onCompleted: () => void;
onFormStateChange: (isDirty: boolean) => void;
}) {
const [createDatabase] = useMutation(DATABASE_CREATE_MUTATION, {
refetchQueries: [DATABASES_TABLE_QUERY],
Expand All @@ -54,25 +86,6 @@ function CreateDatabaseDialogContent({
},
});

const onSubmit = (data: UpdateDatabaseFormData) => {
try {
createDatabase({
variables: {
input: {
slug: data.slug!,
description: data.description,
schema: data.schema!,
relationFigure: data.relationFigure!,
},
},
});
} catch (error) {
toast.error("資料庫建立失敗", {
description: error instanceof Error ? error.message : "未知錯誤",
});
}
};

return (
<DialogContent className="max-h-[85vh] max-w-3xl overflow-y-auto">
<DialogHeader>
Expand All @@ -88,8 +101,20 @@ function CreateDatabaseDialogContent({
schema: "",
relationFigure: "",
}}
onSubmit={onSubmit}
onSubmit={(data) => {
createDatabase({
variables: {
input: {
slug: data.slug,
description: data.description,
schema: data.schema,
relationFigure: data.relationFigure,
},
},
});
}}
action="create"
onFormStateChange={onFormStateChange}
/>
</DialogContent>
);
Expand Down
19 changes: 14 additions & 5 deletions app/(admin)/(question-management)/database/_components/delete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
} from "@/components/ui/alert-dialog";
import { buttonVariants } from "@/components/ui/button";
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
import { useMutation, useSuspenseQuery } from "@apollo/client/react";
import { skipToken, useMutation, useSuspenseQuery } from "@apollo/client/react";
import { Trash } from "lucide-react";
import { useRouter } from "next/navigation";
import { Suspense, useState } from "react";
Expand Down Expand Up @@ -42,6 +42,7 @@ export function DeleteDatabaseDropdownTrigger({ id }: { id: string }) {
<Suspense>
<DeleteDatabaseAlertDialogContent
id={id}
open={open}
onCompleted={() => {
setOpen(false);
router.refresh();
Expand All @@ -66,6 +67,7 @@ export function DeleteDatabaseButtonTrigger({ id }: { id: string }) {
<Suspense>
<DeleteDatabaseAlertDialogContent
id={id}
open={open}
onCompleted={() => {
setOpen(false);
router.push("/database");
Expand All @@ -78,14 +80,21 @@ export function DeleteDatabaseButtonTrigger({ id }: { id: string }) {

function DeleteDatabaseAlertDialogContent({
id,
open,
onCompleted,
}: {
id: string;
open: boolean;
onCompleted: () => void;
}) {
const { data } = useSuspenseQuery(DATABASE_BY_ID_QUERY, {
variables: { id },
});
const { data } = useSuspenseQuery(
DATABASE_BY_ID_QUERY,
open
? {
variables: { id },
}
: skipToken,
);

const [deleteDatabase] = useMutation(DATABASE_DELETE_MUTATION, {
refetchQueries: [DATABASES_TABLE_QUERY],
Expand All @@ -106,7 +115,7 @@ function DeleteDatabaseAlertDialogContent({
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
確定要刪除「{data.database.slug}」資料庫嗎?
確定要刪除「{data?.database.slug}」資料庫嗎?
</AlertDialogTitle>
<AlertDialogDescription>
刪除後將無法復原此資料庫,且相關的題目可能會受到影響。請謹慎操作。
Expand Down
Loading