diff --git a/src/client/components/PublicSetupCard.tsx b/src/client/components/PublicSetupCard.tsx
new file mode 100644
index 0000000..672d8cd
--- /dev/null
+++ b/src/client/components/PublicSetupCard.tsx
@@ -0,0 +1,33 @@
+import { Link } from "@tanstack/react-router";
+
+interface PublicSetupCardProps {
+ setup: {
+ id: number;
+ name: string;
+ createdAt: string;
+ };
+}
+
+export function PublicSetupCard({ setup }: PublicSetupCardProps) {
+ const formattedDate = new Date(setup.createdAt).toLocaleDateString(
+ undefined,
+ {
+ year: "numeric",
+ month: "short",
+ day: "numeric",
+ },
+ );
+
+ return (
+
+
+ {setup.name}
+
+ {formattedDate}
+
+ );
+}
diff --git a/src/client/components/SetupCard.tsx b/src/client/components/SetupCard.tsx
index ac79d9e..f46b691 100644
--- a/src/client/components/SetupCard.tsx
+++ b/src/client/components/SetupCard.tsx
@@ -4,6 +4,7 @@ import { useFormatters } from "../hooks/useFormatters";
interface SetupCardProps {
id: number;
name: string;
+ isPublic?: boolean;
itemCount: number;
totalWeight: number;
totalCost: number;
@@ -12,6 +13,7 @@ interface SetupCardProps {
export function SetupCard({
id,
name,
+ isPublic,
itemCount,
totalWeight,
totalCost,
@@ -24,7 +26,16 @@ export function SetupCard({
className="block w-full text-left bg-white rounded-xl border border-gray-100 hover:border-gray-200 hover:shadow-md transition-all p-4"
>
-
{name}
+
+
+ {name}
+
+ {isPublic && (
+
+ Public
+
+ )}
+
{itemCount} {itemCount === 1 ? "item" : "items"}
diff --git a/src/client/components/SetupsView.tsx b/src/client/components/SetupsView.tsx
index d9a28d9..3babd0f 100644
--- a/src/client/components/SetupsView.tsx
+++ b/src/client/components/SetupsView.tsx
@@ -100,6 +100,7 @@ export function SetupsView() {
key={setup.id}
id={setup.id}
name={setup.name}
+ isPublic={setup.isPublic}
itemCount={setup.itemCount}
totalWeight={setup.totalWeight}
totalCost={setup.totalCost}
diff --git a/src/client/hooks/useSetups.ts b/src/client/hooks/useSetups.ts
index b0f6385..8e0b9da 100644
--- a/src/client/hooks/useSetups.ts
+++ b/src/client/hooks/useSetups.ts
@@ -11,6 +11,7 @@ import {
interface SetupListItem {
id: number;
name: string;
+ isPublic: boolean;
createdAt: string;
updatedAt: string;
itemCount: number;
@@ -38,6 +39,7 @@ interface SetupItemWithCategory {
interface SetupWithItems {
id: number;
name: string;
+ isPublic: boolean;
createdAt: string;
updatedAt: string;
items: SetupItemWithCategory[];
@@ -76,7 +78,7 @@ export function useCreateSetup() {
export function useUpdateSetup(setupId: number) {
const queryClient = useQueryClient();
return useMutation({
- mutationFn: (data: { name?: string }) =>
+ mutationFn: (data: { name?: string; isPublic?: boolean }) =>
apiPut
(`/api/setups/${setupId}`, data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["setups"] });
diff --git a/src/client/routes/setups/$setupId.tsx b/src/client/routes/setups/$setupId.tsx
index 70f3f23..73575cc 100644
--- a/src/client/routes/setups/$setupId.tsx
+++ b/src/client/routes/setups/$setupId.tsx
@@ -10,6 +10,7 @@ import {
useRemoveSetupItem,
useSetup,
useUpdateItemClassification,
+ useUpdateSetup,
} from "../../hooks/useSetups";
import { LucideIcon } from "../../lib/iconData";
@@ -24,6 +25,7 @@ function SetupDetailPage() {
const numericId = Number(setupId);
const { data: setup, isLoading } = useSetup(numericId);
const deleteSetup = useDeleteSetup();
+ const updateSetup = useUpdateSetup(numericId);
const removeItem = useRemoveSetupItem(numericId);
const updateClassification = useUpdateItemClassification(numericId);
@@ -160,6 +162,32 @@ function SetupDetailPage() {
Add Items
+
+ {/* Public toggle */}
+
+
+