-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathquests.$questId.index.tsx
113 lines (104 loc) · 3.2 KB
/
quests.$questId.index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { AppContent } from "@/components/app";
import {
Button,
Empty,
Menu,
MenuItem,
MenuSeparator,
MenuTrigger,
} from "@/components/common";
import {
QuestContent,
QuestCosts,
QuestDetails,
QuestDocuments,
QuestPageHeader,
QuestTimeRequired,
QuestUrls,
StatusSelect,
} from "@/components/quests";
import { api } from "@convex/_generated/api";
import type { Id } from "@convex/_generated/dataModel";
import type { Status } from "@convex/constants";
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useMutation, useQuery } from "convex/react";
import { Ellipsis, Milestone } from "lucide-react";
import { toast } from "sonner";
export const Route = createFileRoute("/_authenticated/_home/quests/$questId/")({
component: QuestDetailRoute,
});
function QuestDetailRoute() {
const { questId } = Route.useParams();
const navigate = useNavigate();
const user = useQuery(api.users.getCurrent);
const canEdit = user?.role === "admin";
// TODO: Opportunity to combine these queries?
const quest = useQuery(api.quests.getById, {
questId: questId as Id<"quests">,
});
const userQuest = useQuery(api.userQuests.getByQuestId, {
questId: questId as Id<"quests">,
});
const changeStatus = useMutation(api.userQuests.setStatus);
const deleteForever = useMutation(api.userQuests.deleteForever);
const handleStatusChange = (status: Status) => {
changeStatus({ questId: questId as Id<"quests">, status: status });
};
const handleRemoveQuest = (questId: Id<"quests">, title: string) => {
deleteForever({ questId }).then(() => {
toast(`Removed ${title} quest`);
navigate({ to: "/" });
});
};
// TODO: Improve loading state to prevent flash of empty
if (quest === undefined || userQuest === undefined) return;
if (quest === null || userQuest === null)
return <Empty title="Quest not found" icon={Milestone} />;
return (
<AppContent>
<QuestPageHeader quest={quest}>
<StatusSelect
status={userQuest.status as Status}
onChange={handleStatusChange}
/>
<MenuTrigger>
<Button
aria-label="Quest settings"
variant="icon"
icon={Ellipsis}
className="-mr-2"
/>
<Menu placement="bottom end">
{canEdit && (
<>
<MenuItem
href={{
to: "/quests/$questId/edit",
params: { questId },
}}
>
Edit quest
</MenuItem>
<MenuSeparator />
</>
)}
<MenuItem
onAction={() => handleRemoveQuest(quest._id, quest.title)}
>
Remove quest
</MenuItem>
</Menu>
</MenuTrigger>
</QuestPageHeader>
<div className="flex flex-col gap-6">
<QuestDetails>
<QuestCosts quest={quest} />
<QuestTimeRequired quest={quest} />
</QuestDetails>
<QuestDocuments quest={quest} />
<QuestUrls urls={quest.urls} />
<QuestContent initialContent={quest.content} editable={false} />
</div>
</AppContent>
);
}