Skip to content

Commit 5e4589b

Browse files
feat: new feed edit (#198)
* feat: update the feed editor * feat: improve performance, and fix bugs * feat: revert local development change * add routegen to pretttier ignore * fix: resolve code rabbit comments * fix some nitpick comments * fix prettier and build config * formats * merge --------- Co-authored-by: Elliot Braem <elliot@ejlbraem.com>
1 parent 06c695d commit 5e4589b

38 files changed

+2412
-856
lines changed

.prettierignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ node_modules
44
.turbo
55
.next
66
.docusaurus
7-
packages/shared-db/migrations
87
apps/app/src/routeTree.gen.ts
8+
packages/shared-db/migrations
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import type { FeedConfig } from "@curatedotfun/types";
2+
import { Button } from "../ui/button";
3+
import { Loading } from "../ui/loading";
4+
5+
interface EditFeedActionsProps {
6+
currentConfig: FeedConfig | null;
7+
onSaveChanges: () => Promise<void>;
8+
onDeleteFeed: () => Promise<void>;
9+
updateFeedMutation: {
10+
isPending: boolean;
11+
};
12+
deleteFeedMutation: {
13+
isPending: boolean;
14+
};
15+
}
16+
17+
export function EditFeedActions({
18+
onSaveChanges,
19+
onDeleteFeed,
20+
updateFeedMutation,
21+
deleteFeedMutation,
22+
}: EditFeedActionsProps) {
23+
return (
24+
<div className="bg-white p-6 border border-gray-200 rounded-lg">
25+
<div className="flex flex-col sm:flex-row gap-4 pt-2">
26+
<Button
27+
onClick={onSaveChanges}
28+
disabled={updateFeedMutation.isPending}
29+
className="flex-1 sm:flex-none"
30+
size="lg"
31+
>
32+
{updateFeedMutation.isPending ? (
33+
<>
34+
<Loading />
35+
<span className="ml-2">Saving...</span>
36+
</>
37+
) : (
38+
"Save Changes"
39+
)}
40+
</Button>
41+
<Button
42+
variant="destructive"
43+
onClick={onDeleteFeed}
44+
disabled={deleteFeedMutation.isPending}
45+
className="flex-1 sm:flex-none"
46+
size="lg"
47+
>
48+
{deleteFeedMutation.isPending ? (
49+
<>
50+
<Loading />
51+
<span className="ml-2">Deleting...</span>
52+
</>
53+
) : (
54+
"Delete Feed"
55+
)}
56+
</Button>
57+
</div>
58+
</div>
59+
);
60+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import type { FeedConfig } from "@curatedotfun/types";
2+
import { useState, useRef } from "react";
3+
import { JsonEditor } from "../content-progress/JsonEditor";
4+
import { Button } from "../ui/button";
5+
import { Label } from "../ui/label";
6+
import { EditFeedForm, type EditFeedFormRef } from "./EditFeedForm";
7+
import { toast } from "@/hooks/use-toast";
8+
9+
interface EditFeedConfigSectionProps {
10+
jsonString: string;
11+
currentConfig: FeedConfig | null;
12+
onJsonChange: (newJsonString: string) => void;
13+
onConfigChange: (config: FeedConfig) => void;
14+
}
15+
16+
export function EditFeedConfigSection({
17+
jsonString,
18+
currentConfig,
19+
onJsonChange,
20+
onConfigChange,
21+
}: EditFeedConfigSectionProps) {
22+
const [isJsonMode, setIsJsonMode] = useState(false);
23+
const formRef = useRef<EditFeedFormRef>(null);
24+
25+
const handleConfigChange = (config: FeedConfig) => {
26+
onConfigChange(config);
27+
try {
28+
onJsonChange(JSON.stringify(config, null, 2));
29+
} catch (error) {
30+
console.error("Failed to stringify config:", error);
31+
toast({
32+
title: "Error",
33+
description:
34+
"Failed to update JSON configuration. Please check the console for details.",
35+
variant: "destructive",
36+
});
37+
}
38+
};
39+
40+
const handleSwitchToFormMode = () => {
41+
setIsJsonMode(false);
42+
// Trigger form update after switching to form mode
43+
setTimeout(() => {
44+
formRef.current?.updateFromConfig();
45+
}, 0);
46+
};
47+
48+
return (
49+
<div className="bg-white p-6 border border-gray-200 rounded-lg">
50+
<div className="space-y-6">
51+
<div className="flex items-center justify-between">
52+
<div className="space-y-2">
53+
<h2 className="text-xl font-semibold">Feed Configuration</h2>
54+
<p className="text-gray-600">
55+
{isJsonMode
56+
? "Edit the JSON configuration directly to fine-tune your feed settings"
57+
: "Use the form below to easily configure your feed settings"}
58+
</p>
59+
</div>
60+
<div className="flex gap-2">
61+
<Button
62+
variant={!isJsonMode ? "default" : "outline"}
63+
size="sm"
64+
onClick={handleSwitchToFormMode}
65+
>
66+
Form View
67+
</Button>
68+
<Button
69+
variant={isJsonMode ? "default" : "outline"}
70+
size="sm"
71+
onClick={() => setIsJsonMode(true)}
72+
>
73+
JSON View
74+
</Button>
75+
</div>
76+
</div>
77+
78+
{isJsonMode ? (
79+
<div className="space-y-2">
80+
<Label>Feed Configuration (JSON)</Label>
81+
<JsonEditor
82+
jsonContent={jsonString}
83+
onContentChange={onJsonChange}
84+
/>
85+
</div>
86+
) : (
87+
<EditFeedForm
88+
ref={formRef}
89+
currentConfig={currentConfig}
90+
onConfigChange={handleConfigChange}
91+
/>
92+
)}
93+
</div>
94+
</div>
95+
);
96+
}

0 commit comments

Comments
 (0)