Skip to content
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ node_modules
.turbo
.next
.docusaurus
packages/shared-db/migrations
apps/app/src/routeTree.gen.ts
packages/shared-db/migrations
60 changes: 60 additions & 0 deletions apps/app/src/components/feed/EditFeedActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import type { FeedConfig } from "@curatedotfun/types";
import { Button } from "../ui/button";
import { Loading } from "../ui/loading";

interface EditFeedActionsProps {
currentConfig: FeedConfig | null;
onSaveChanges: () => Promise<void>;
onDeleteFeed: () => Promise<void>;
updateFeedMutation: {
isPending: boolean;
};
deleteFeedMutation: {
isPending: boolean;
};
}

export function EditFeedActions({
onSaveChanges,
onDeleteFeed,
updateFeedMutation,
deleteFeedMutation,
}: EditFeedActionsProps) {
return (
<div className="bg-white p-6 border border-gray-200 rounded-lg">
<div className="flex flex-col sm:flex-row gap-4 pt-2">
<Button
onClick={onSaveChanges}
disabled={updateFeedMutation.isPending}
className="flex-1 sm:flex-none"
size="lg"
>
{updateFeedMutation.isPending ? (
<>
<Loading />
<span className="ml-2">Saving...</span>
</>
) : (
"Save Changes"
)}
</Button>
<Button
variant="destructive"
onClick={onDeleteFeed}
disabled={deleteFeedMutation.isPending}
className="flex-1 sm:flex-none"
size="lg"
>
{deleteFeedMutation.isPending ? (
<>
<Loading />
<span className="ml-2">Deleting...</span>
</>
) : (
"Delete Feed"
)}
</Button>
</div>
</div>
);
}
96 changes: 96 additions & 0 deletions apps/app/src/components/feed/EditFeedConfigSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import type { FeedConfig } from "@curatedotfun/types";
import { useState, useRef } from "react";
import { JsonEditor } from "../content-progress/JsonEditor";
import { Button } from "../ui/button";
import { Label } from "../ui/label";
import { EditFeedForm, type EditFeedFormRef } from "./EditFeedForm";
import { toast } from "@/hooks/use-toast";

interface EditFeedConfigSectionProps {
jsonString: string;
currentConfig: FeedConfig | null;
onJsonChange: (newJsonString: string) => void;
onConfigChange: (config: FeedConfig) => void;
}

export function EditFeedConfigSection({
jsonString,
currentConfig,
onJsonChange,
onConfigChange,
}: EditFeedConfigSectionProps) {
const [isJsonMode, setIsJsonMode] = useState(false);
const formRef = useRef<EditFeedFormRef>(null);

const handleConfigChange = (config: FeedConfig) => {
onConfigChange(config);
try {
onJsonChange(JSON.stringify(config, null, 2));
} catch (error) {
console.error("Failed to stringify config:", error);
toast({
title: "Error",
description:
"Failed to update JSON configuration. Please check the console for details.",
variant: "destructive",
});
}
};

const handleSwitchToFormMode = () => {
setIsJsonMode(false);
// Trigger form update after switching to form mode
setTimeout(() => {
formRef.current?.updateFromConfig();
}, 0);
};

return (
<div className="bg-white p-6 border border-gray-200 rounded-lg">
<div className="space-y-6">
<div className="flex items-center justify-between">
<div className="space-y-2">
<h2 className="text-xl font-semibold">Feed Configuration</h2>
<p className="text-gray-600">
{isJsonMode
? "Edit the JSON configuration directly to fine-tune your feed settings"
: "Use the form below to easily configure your feed settings"}
</p>
</div>
<div className="flex gap-2">
<Button
variant={!isJsonMode ? "default" : "outline"}
size="sm"
onClick={handleSwitchToFormMode}
>
Form View
</Button>
<Button
variant={isJsonMode ? "default" : "outline"}
size="sm"
onClick={() => setIsJsonMode(true)}
>
JSON View
</Button>
</div>
</div>

{isJsonMode ? (
<div className="space-y-2">
<Label>Feed Configuration (JSON)</Label>
<JsonEditor
jsonContent={jsonString}
onContentChange={onJsonChange}
/>
</div>
) : (
<EditFeedForm
ref={formRef}
currentConfig={currentConfig}
onConfigChange={handleConfigChange}
/>
)}
</div>
</div>
);
}
Loading