Skip to content

Commit 08f9eed

Browse files
committed
Added edit button to card modal
1 parent 47922ba commit 08f9eed

File tree

6 files changed

+75
-58
lines changed

6 files changed

+75
-58
lines changed

docs/code-guidelines.md

Whitespace-only changes.

src/renderer/src/app/collections.tsx

+9-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { CardBundle } from "@shared/types";
88
import Fuse from "fuse.js";
99
import { useEffect, useRef, useState } from "react";
1010
import { toast } from "sonner";
11-
import { useTheme } from "@/components/theme-provider"
11+
import { useTheme } from "@/components/theme-provider";
1212

1313
interface CollectionsPageProps {
1414
setPage: (page: string) => void;
@@ -23,18 +23,12 @@ export default function CollectionsPage({ setPage, setChatID, cardBundles, syncC
2323
const [searchResults, setSearchResults] = useState<CardBundle[]>(cardBundles);
2424
const [sortBy, setSortBy] = useState<string>("alphabetical");
2525
const [descending, setDescending] = useState<boolean>(true);
26-
const { setTheme } = useTheme()
26+
const { setTheme } = useTheme();
2727

2828
useEffect(() => {
2929
setTheme("darker");
3030
}, []);
3131

32-
33-
34-
35-
36-
37-
3832
// TODO, edit card bundle type to also include all data from the card table
3933
// then add sort by "imported" which is the inserted_at column in the db
4034
const sortByNameAndValue = [
@@ -190,7 +184,13 @@ export default function CollectionsPage({ setPage, setChatID, cardBundles, syncC
190184
cardBundle={cardBundle}
191185
syncCardBundles={syncCardBundles}
192186
openCardModal={() => {
193-
createModal(<CardModal cardBundle={cardBundle} onCreateChat={createChatHandler} />);
187+
createModal(
188+
<CardModal
189+
cardBundle={cardBundle}
190+
onCreateChat={createChatHandler}
191+
syncCardBundles={syncCardBundles}
192+
/>
193+
);
194194
}}
195195
/>
196196
);

src/renderer/src/components/Card.tsx

+11-34
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { DialogConfig, useApp } from "@/components/AppContext";
2+
import EditCardModal from "@/components/EditCardModal";
13
import Tag from "@/components/Tag";
24
import {
35
ContextMenu,
@@ -6,24 +8,19 @@ import {
68
ContextMenuShortcut,
79
ContextMenuTrigger
810
} from "@/components/ui/context-menu";
11+
import { queries } from "@/lib/queries";
912
import { PencilIcon, TrashIcon } from "@heroicons/react/24/solid";
10-
import { CardBundle, CardFormData } from "@shared/types";
13+
import { CardBundle } from "@shared/types";
1114
import { motion, useMotionValue } from "framer-motion";
1215
import { CardPattern } from "./ui/card-pattern";
13-
import { DeepPartial } from "react-hook-form";
14-
import { DialogConfig, useApp } from "@/components/AppContext";
15-
import { queries } from "@/lib/queries";
16-
import CharacterForm from "@/components/CharacterForm";
17-
import { cardFormDataToCardData } from "@/lib/utils";
18-
import { toast } from "sonner";
1916
interface CardProps {
2017
cardBundle: CardBundle;
2118
syncCardBundles: () => void;
2219
openCardModal: () => void;
2320
}
2421

2522
function Card({ cardBundle, syncCardBundles, openCardModal }: CardProps) {
26-
const { createModal, closeModal, createDialog } = useApp();
23+
const { createModal, createDialog } = useApp();
2724
let mouseX = useMotionValue(0);
2825
let mouseY = useMotionValue(0);
2926

@@ -33,31 +30,7 @@ function Card({ cardBundle, syncCardBundles, openCardModal }: CardProps) {
3330
mouseY.set(clientY - top);
3431
}
3532

36-
const onEdit = () => {
37-
const successfulSubmitHandler = async (data: CardFormData) => {
38-
const cardData = cardFormDataToCardData(data);
39-
40-
const res = await window.api.blob.cards.update(
41-
cardBundle.id,
42-
cardData,
43-
data.character.bannerURI ?? null,
44-
data.character.avatarURI ?? null
45-
);
46-
syncCardBundles();
47-
if (res.kind === "err") {
48-
toast.error("Error updating card.");
49-
console.error("An error occurred while running the update function:", res.error);
50-
return;
51-
}
52-
closeModal();
53-
};
54-
55-
createModal(
56-
<div className="h-[80vh] w-[36rem] overflow-hidden rounded-xl">
57-
<CharacterForm cardBundle={cardBundle} formType="edit" onSuccessfulSubmit={successfulSubmitHandler} />
58-
</div>
59-
);
60-
};
33+
const handleEdit = () => {};
6134

6235
const onDelete = () => {
6336
const config: DialogConfig = {
@@ -123,7 +96,11 @@ function Card({ cardBundle, syncCardBundles, openCardModal }: CardProps) {
12396
</motion.button>
12497
</ContextMenuTrigger>
12598
<ContextMenuContent className="w-40 px-1 py-2">
126-
<ContextMenuItem onSelect={onEdit}>
99+
<ContextMenuItem
100+
onSelect={() => {
101+
createModal(<EditCardModal cardBundle={cardBundle} syncCardBundles={syncCardBundles} />);
102+
}}
103+
>
127104
Edit
128105
<ContextMenuShortcut>
129106
<PencilIcon className="size-4" />

src/renderer/src/components/CardModal.tsx

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
import Dropdown from "@/components/Dropdown";
22
import { Button } from "@/components/ui/button";
3-
import { ArrowUpOnSquareIcon, ChatBubbleLeftRightIcon } from "@heroicons/react/24/solid";
3+
import { ArrowUpOnSquareIcon, ChatBubbleLeftRightIcon, PencilIcon } from "@heroicons/react/24/solid";
44
import { CardBundle } from "@shared/types";
55
import { queries } from "../lib/queries";
66
import { toast } from "sonner";
77
import Tag from "@/components/Tag";
88
import { time } from "@/lib/time";
9-
interface Props {
9+
import EditCardModal from "@/components/EditCardModal";
10+
import { useApp } from "@/components/AppContext";
11+
interface CardModalProps {
1012
cardBundle: CardBundle;
13+
syncCardBundles: () => void;
1114
onCreateChat: (cardID: number, greeting: string) => void;
1215
}
1316

14-
function CardModal({ cardBundle, onCreateChat }: Props) {
17+
function CardModal({ cardBundle, syncCardBundles, onCreateChat }: CardModalProps) {
18+
const { createModal, closeModal } = useApp();
19+
1520
const handleExport = async () => {
1621
const cardDirRes = await queries.getCardDir(cardBundle.id);
1722

@@ -30,6 +35,11 @@ function CardModal({ cardBundle, onCreateChat }: Props) {
3035
toast.success("Card successfully exported to zip!");
3136
};
3237

38+
const handleEdit = () => {
39+
closeModal();
40+
createModal(<EditCardModal cardBundle={cardBundle} syncCardBundles={syncCardBundles} />);
41+
};
42+
3343
return (
3444
<div className="flex w-[45rem] items-center justify-center rounded-lg bg-neutral-800">
3545
<div className="scroll-secondary h-[60rem] overflow-y-scroll rounded-lg">
@@ -68,6 +78,10 @@ function CardModal({ cardBundle, onCreateChat }: Props) {
6878
</div>
6979
</div>
7080
<div className="mt-6 flex justify-end space-x-4 border-b border-t border-neutral-700">
81+
<Button variant="outline" className="group m-2 h-10 w-16 border-none bg-transparent" onClick={handleEdit}>
82+
<PencilIcon className="size-6 text-neutral-400 transition duration-200 ease-out group-hover:text-neutral-200" />
83+
</Button>
84+
7185
<Button variant="outline" className="group m-2 h-10 w-16 border-none bg-transparent" onClick={handleExport}>
7286
<ArrowUpOnSquareIcon className="size-6 text-neutral-400 transition duration-200 ease-out group-hover:text-neutral-200" />
7387
</Button>

src/renderer/src/components/ChatsSidebar.tsx

-12
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ export default function ChatsSidebar({ chatID, personaBundle, syncChatHistory, s
2626
const [sidebarOpen, setSidebarOpen] = useState(true);
2727
const { createModal, createDialog } = useApp();
2828

29-
3029
useEffect(() => {
3130
syncRecentChats();
3231
}, []);
@@ -108,9 +107,6 @@ export default function ChatsSidebar({ chatID, personaBundle, syncChatHistory, s
108107
};
109108
createDialog(config);
110109
}}
111-
cloneChat={() => {
112-
// TODO clone chat with the given id
113-
}}
114110
id={chat.chat_id.toString()}
115111
avatarURI={chat.avatarURI || ""}
116112
name={chat.name}
@@ -157,7 +153,6 @@ interface RecentChatProps {
157153
active: boolean;
158154
deleteChat: () => void;
159155
resetChat: () => void;
160-
cloneChat: () => void;
161156
className?: string;
162157
[x: string]: any;
163158
}
@@ -170,7 +165,6 @@ function RecentChat({
170165
active,
171166
deleteChat,
172167
resetChat,
173-
cloneChat,
174168
className,
175169
...rest
176170
}: RecentChatProps) {
@@ -208,12 +202,6 @@ function RecentChat({
208202
<ArrowPathIcon className="size-4" />
209203
</ContextMenuShortcut>
210204
</ContextMenuItem>
211-
<ContextMenuItem disabled>
212-
Clone
213-
<ContextMenuShortcut>
214-
<DocumentDuplicateIcon className="size-4" />
215-
</ContextMenuShortcut>
216-
</ContextMenuItem>
217205
</ContextMenuContent>
218206
</ContextMenu>
219207
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { useApp } from "@/components/AppContext";
2+
import CharacterForm from "@/components/CharacterForm";
3+
import { cardFormDataToCardData } from "@/lib/utils";
4+
import { CardBundle, CardFormData } from "@shared/types";
5+
import { toast } from "sonner";
6+
7+
interface EditCardModalProps {
8+
cardBundle: CardBundle;
9+
syncCardBundles: () => void;
10+
}
11+
12+
export default function EditCardModal({ cardBundle, syncCardBundles }: EditCardModalProps) {
13+
const { closeModal } = useApp();
14+
15+
const handleSuccessfulSubmit = async (data: CardFormData) => {
16+
const cardData = cardFormDataToCardData(data);
17+
18+
const res = await window.api.blob.cards.update(
19+
cardBundle.id,
20+
cardData,
21+
data.character.bannerURI ?? null,
22+
data.character.avatarURI ?? null
23+
);
24+
syncCardBundles();
25+
if (res.kind === "err") {
26+
toast.error("Error updating card.");
27+
console.error("An error occurred while running the update function:", res.error);
28+
return;
29+
}
30+
closeModal();
31+
};
32+
33+
return (
34+
<div className="h-[80vh] w-[36rem] overflow-hidden rounded-xl">
35+
<CharacterForm cardBundle={cardBundle} formType="edit" onSuccessfulSubmit={handleSuccessfulSubmit} />
36+
</div>
37+
);
38+
}

0 commit comments

Comments
 (0)