diff --git a/apps/web/src/components/mobile-detail-view.tsx b/apps/web/src/components/mobile-detail-view.tsx new file mode 100644 index 0000000..fb47873 --- /dev/null +++ b/apps/web/src/components/mobile-detail-view.tsx @@ -0,0 +1,95 @@ +import { Icon } from "./icon"; + +interface Field { + label: string; + value: string | number | boolean | null; + type?: "text" | "code" | "json" | "boolean"; +} + +interface MobileDetailViewProps { + title: string; + subtitle?: string; + fields: Field[]; + onEdit: () => void; + onDelete: () => void; + onBack: () => void; +} + +export const MobileDetailView: React.FC = ({ + title, + subtitle, + fields, + onEdit, + onDelete, + onBack, +}) => { + const renderValue = (field: Field) => { + if (field.value === null || field.value === undefined) { + return Not set; + } + + if (field.type === "boolean") { + return field.value ? ( + Yes + ) : ( + No + ); + } + + if (field.type === "code" || field.type === "json") { + return ( +
+          {typeof field.value === "string" ? field.value : JSON.stringify(field.value, null, 2)}
+        
+ ); + } + + return {String(field.value)}; + }; + + return ( +
+
+ +
+

{title}

+ {subtitle &&

{subtitle}

} +
+
+ + +
+
+ +
+ {fields.map((field, index) => ( +
+ +
{renderValue(field)}
+
+ ))} +
+
+ ); +}; diff --git a/apps/web/src/components/mobile-edit-view.tsx b/apps/web/src/components/mobile-edit-view.tsx new file mode 100644 index 0000000..73c26fc --- /dev/null +++ b/apps/web/src/components/mobile-edit-view.tsx @@ -0,0 +1,162 @@ +import { useState } from "react"; +import { Icon } from "./icon"; + +interface FormField { + name: string; + label: string; + type: "text" | "textarea" | "number" | "select" | "checkbox" | "code"; + value: string | number | boolean; + options?: { value: string; label: string }[]; + placeholder?: string; + required?: boolean; + rows?: number; +} + +interface MobileEditViewProps { + title: string; + fields?: FormField[]; + onSave: (data: Record) => void; + onCancel: () => void; + isSaving?: boolean; + children?: React.ReactNode; +} + +export const MobileEditView: React.FC = ({ + title, + fields, + onSave, + onCancel, + isSaving = false, + children, +}) => { + const [formData, setFormData] = useState>( + () => { + const initial: Record = {}; + fields?.forEach((field) => { + initial[field.name] = field.value; + }); + return initial; + } + ); + + const handleChange = (name: string, value: string | number | boolean) => { + setFormData((prev) => ({ ...prev, [name]: value })); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + onSave(formData); + }; + + return ( +
+
+ +

{title}

+ +
+ +
+ {children || fields?.map((field) => ( +
+ + + {field.type === "textarea" && ( +