diff --git a/src/components/FeedDialog.tsx b/src/components/FeedDialog.tsx
new file mode 100644
index 0000000..10864ba
--- /dev/null
+++ b/src/components/FeedDialog.tsx
@@ -0,0 +1,83 @@
+import {
+ Dialog,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ } from "./ui/dialog";
+ import { Input } from "./ui/input";
+ import { Label } from "./ui/label";
+ import { Checkbox } from "./ui/checkbox";
+ import { Button } from "./ui/button";
+ import { useState, useEffect } from "react";
+
+ export interface FeedDialogProps {
+ open: boolean;
+ onClose: () => void;
+ onSubmit: (name: string, isPublic: boolean) => void;
+ initialName?: string;
+ initialIsPublic?: boolean;
+ mode?: "create" | "edit";
+ }
+
+ export function FeedDialog({
+ open,
+ onClose,
+ onSubmit,
+ initialName = "",
+ initialIsPublic = false,
+ mode = "create",
+ }: FeedDialogProps) {
+ const [name, setName] = useState(initialName);
+ const [isPublic, setIsPublic] = useState(initialIsPublic);
+
+ useEffect(() => {
+ setName(initialName);
+ setIsPublic(initialIsPublic);
+ }, [initialName, initialIsPublic]);
+
+ const handleSubmit = () => {
+ if (name.trim()) {
+ onSubmit(name.trim(), isPublic);
+ onClose();
+ }
+ };
+
+ return (
+
+ );
+ }
+
\ No newline at end of file
diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx
new file mode 100644
index 0000000..ac2dd53
--- /dev/null
+++ b/src/components/ui/badge.tsx
@@ -0,0 +1,15 @@
+// components/ui/badge.tsx
+import { cn } from "@/lib/utils";
+
+export function Badge({ children, className }: { children: React.ReactNode; className?: string }) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx
new file mode 100644
index 0000000..58ab795
--- /dev/null
+++ b/src/components/ui/checkbox.tsx
@@ -0,0 +1,23 @@
+import * as React from "react";
+import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
+import { Check } from "lucide-react";
+import { cn } from "@/lib/utils";
+
+export const Checkbox = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+
+
+));
+Checkbox.displayName = CheckboxPrimitive.Root.displayName;
diff --git a/src/lib/api.ts b/src/lib/api.ts
index e07fb17..5bc62e9 100644
--- a/src/lib/api.ts
+++ b/src/lib/api.ts
@@ -91,11 +91,11 @@ export const addNewFeed = async (name: string, isPublic: boolean) => {
try {
const token = getToken();
if (!token) {
- throw new Error('Authentication required');
+ throw new Error("Authentication required");
}
const response = await userDataApi.post(
- '/api/addnewfeed',
+ "/api/addnewfeed",
{
Name: name,
IsPublic: isPublic,
@@ -108,10 +108,37 @@ export const addNewFeed = async (name: string, isPublic: boolean) => {
);
return response.data;
} catch (error: any) {
- throw error.response?.data || { success: false, message: 'Network error' };
+ throw error.response?.data || { success: false, message: "Network error" };
}
};
+export const updateFeed = async (feedId: string, name: string, isPublic: boolean): Promise => {
+ try {
+ const token = getToken();
+ if (!token) {
+ throw new Error("Authentication required");
+ }
+
+ const response = await userDataApi.patch(
+ `/api/updatefeed`,
+ {
+ feedId: feedId,
+ Name: name,
+ IsPublic: isPublic,
+ },
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ }
+ );
+ return response.status === 200;
+ } catch (error: any) {
+ return false;
+ }
+};
+
+
export const deleteFeed = async (feedId: string) => {
try {
diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx
index 6f950e5..201facc 100644
--- a/src/pages/DashboardPage.tsx
+++ b/src/pages/DashboardPage.tsx
@@ -3,7 +3,7 @@ import { useNavigate } from "react-router-dom";
import { toast } from "sonner";
import { isAuthenticated } from "@/lib/auth";
import { useFeedStore } from "@/lib/store";
-import { addNewFeed } from "@/lib/api";
+import { addNewFeed, updateFeed } from "@/lib/api";
import { formatDateTime, getTimeRangeOptions } from "@/lib/timeRanges";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
@@ -15,10 +15,11 @@ import {
SelectValue,
} from "@/components/ui/select";
import { Skeleton } from "@/components/ui/skeleton";
-import { Plus, RefreshCw, ScanBarcode } from "lucide-react";
+import { Plus, RefreshCw, ScanBarcode, Edit, Copy } from "lucide-react";
import { FeedChart } from "@/components/FeedChart";
import { FeedActions } from "@/components/FeedActions";
import { Alert, AlertDescription } from "@/components/ui/alert";
+import { FeedDialog } from "@/components/FeedDialog";
export function DashboardPage() {
const navigate = useNavigate();
@@ -36,7 +37,6 @@ export function DashboardPage() {
deleteFeed,
} = useFeedStore();
- // Check if user is authenticated
useEffect(() => {
if (!isAuthenticated()) {
toast.error("Please login to access the dashboard");
@@ -44,11 +44,9 @@ export function DashboardPage() {
return;
}
- // Fetch feeds on component mount
fetchFeeds();
}, [navigate, fetchFeeds]);
- // Handle time range change
const handleTimeRangeChange = (value: string) => {
setTimeRangeValue(value);
const selectedOption = getTimeRangeOptions().find(option => option.value === value);
@@ -58,36 +56,49 @@ export function DashboardPage() {
}
};
- // Handle add new feed
- const handleAddNewFeed = async () => {
- try {
- const defaultName = `Untitled Feed ${new Date().toLocaleString()}`;
- const response = await addNewFeed(defaultName);
+ const [isDialogOpen, setDialogOpen] = useState(false);
+ const [dialogMode, setDialogMode] = useState<"create" | "edit">("create");
+ const [editFeedData, setEditFeedData] = useState<{ id: string; name: string; isPublic: boolean } | null>(null);
- if (response.success) {
- toast.success("New feed created successfully");
- fetchFeeds();
- } else {
- toast.error("Failed to create new feed");
+ const handleAddNewFeed = () => {
+ setDialogMode("create");
+ setEditFeedData(null);
+ setDialogOpen(true);
+ };
+
+ const handleDialogSubmit = async (name: string, isPublic: boolean) => {
+ try {
+ if (dialogMode === "create") {
+ const response = await addNewFeed(name, isPublic);
+ if (response.success) {
+ toast.success("Feed created successfully");
+ fetchFeeds();
+ } else {
+ toast.error(response.message || "Failed to create feed");
+ }
+ } else if (dialogMode === "edit" && editFeedData) {
+ const success = await updateFeed(editFeedData.id, name, isPublic);
+ if (success) {
+ toast.success("Feed updated successfully");
+ fetchFeeds();
+ } else {
+ toast.error("Failed to update feed");
+ fetchFeeds();
+ }
}
- } catch (error) {
- toast.error("An error occurred while creating a new feed");
- console.error(error);
+ } catch (error: any) {
+ toast.error(error.message || "An error occurred");
}
};
- // Handle refresh
const handleRefresh = async () => {
- // First refresh the feeds list
await fetchFeeds();
- // Then refresh current feed data if a feed is selected
if (selectedFeed) {
await refreshCurrentFeedData();
}
toast.success("Data refreshed");
};
- // Handle delete feed
const handleDeleteFeed = async (feedId: string) => {
try {
await deleteFeed(feedId);
@@ -108,7 +119,6 @@ export function DashboardPage() {
- {/* Button to add a new feed */}
);
-}
\ No newline at end of file
+}