@fluid-app/fluid-cli-portal 0.1.31 → 0.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +51 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/templates/base/.gitignore.template +27 -0
- package/templates/base/AGENTS.md +36 -0
- package/templates/base/skills/fluid-portal-authoring/SKILL.md +153 -0
- package/templates/base/src/main.tsx +2 -2
- package/templates/base/src/portal.config.ts +8 -34
- package/templates/starter/README.md.template +122 -181
- package/templates/base/src/navigation.config.ts +0 -26
- package/templates/base/src/screens/Dashboard.tsx +0 -133
- package/templates/base/src/screens/ExampleForm.tsx +0 -177
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Example Form Screen
|
|
3
|
-
*
|
|
4
|
-
* Demonstrates how to build forms in a portal using
|
|
5
|
-
* React Hook Form + Zod for validation.
|
|
6
|
-
*
|
|
7
|
-
* Uncomment the nav entry and import in portal.config.ts to enable.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { z } from "zod";
|
|
11
|
-
import { useZodForm } from "@fluid-app/ui-primitives";
|
|
12
|
-
|
|
13
|
-
// =============================================================================
|
|
14
|
-
// Zod Schema
|
|
15
|
-
// Define your form validation schema here
|
|
16
|
-
// =============================================================================
|
|
17
|
-
|
|
18
|
-
const contactFormSchema = z.object({
|
|
19
|
-
name: z.string().min(1, "Name is required").max(100, "Name is too long"),
|
|
20
|
-
email: z.string().email("Invalid email address"),
|
|
21
|
-
subject: z
|
|
22
|
-
.string()
|
|
23
|
-
.min(1, "Subject is required")
|
|
24
|
-
.max(200, "Subject is too long"),
|
|
25
|
-
message: z
|
|
26
|
-
.string()
|
|
27
|
-
.min(10, "Message must be at least 10 characters")
|
|
28
|
-
.max(2000, "Message is too long"),
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
type ContactFormData = z.infer<typeof contactFormSchema>;
|
|
32
|
-
|
|
33
|
-
// =============================================================================
|
|
34
|
-
// Example Form Screen
|
|
35
|
-
// =============================================================================
|
|
36
|
-
|
|
37
|
-
export function ExampleFormScreen() {
|
|
38
|
-
const {
|
|
39
|
-
register,
|
|
40
|
-
handleSubmit,
|
|
41
|
-
reset,
|
|
42
|
-
formState: { errors, isSubmitting, isSubmitSuccessful },
|
|
43
|
-
} = useZodForm<ContactFormData>(contactFormSchema);
|
|
44
|
-
|
|
45
|
-
const onSubmit = async (_data: ContactFormData) => {
|
|
46
|
-
// Replace with your API call, e.g.:
|
|
47
|
-
// const result = await apiClient.post("/contacts", _data);
|
|
48
|
-
|
|
49
|
-
// Simulate API delay
|
|
50
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
51
|
-
|
|
52
|
-
reset(undefined, { keepIsSubmitSuccessful: true });
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<div className="space-y-6">
|
|
57
|
-
{/* Header */}
|
|
58
|
-
<div>
|
|
59
|
-
<h1 className="text-foreground text-2xl font-bold">Example Form</h1>
|
|
60
|
-
<p className="text-muted-foreground mt-1 text-sm">
|
|
61
|
-
Demonstrates React Hook Form + Zod validation. Replace this with your
|
|
62
|
-
own form.
|
|
63
|
-
</p>
|
|
64
|
-
</div>
|
|
65
|
-
|
|
66
|
-
{/* Form Card */}
|
|
67
|
-
<div className="border-border bg-background rounded-lg border p-6 shadow-sm">
|
|
68
|
-
{isSubmitSuccessful ? (
|
|
69
|
-
<div className="border-accent bg-accent text-accent-foreground rounded-lg border p-4 text-sm">
|
|
70
|
-
Form submitted successfully!
|
|
71
|
-
</div>
|
|
72
|
-
) : (
|
|
73
|
-
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
|
|
74
|
-
{/* Name field */}
|
|
75
|
-
<div>
|
|
76
|
-
<label
|
|
77
|
-
htmlFor="name"
|
|
78
|
-
className="text-foreground block text-sm font-medium"
|
|
79
|
-
>
|
|
80
|
-
Name
|
|
81
|
-
</label>
|
|
82
|
-
<input
|
|
83
|
-
id="name"
|
|
84
|
-
type="text"
|
|
85
|
-
{...register("name")}
|
|
86
|
-
className="border-input bg-background text-foreground focus:border-ring focus:ring-ring mt-1 block w-full rounded-md border px-3 py-2 text-sm shadow-sm focus:ring-1 focus:outline-none"
|
|
87
|
-
placeholder="Jane Smith"
|
|
88
|
-
/>
|
|
89
|
-
{errors.name && (
|
|
90
|
-
<p className="text-destructive mt-1 text-sm">
|
|
91
|
-
{errors.name.message}
|
|
92
|
-
</p>
|
|
93
|
-
)}
|
|
94
|
-
</div>
|
|
95
|
-
|
|
96
|
-
{/* Email field */}
|
|
97
|
-
<div>
|
|
98
|
-
<label
|
|
99
|
-
htmlFor="email"
|
|
100
|
-
className="text-foreground block text-sm font-medium"
|
|
101
|
-
>
|
|
102
|
-
Email
|
|
103
|
-
</label>
|
|
104
|
-
<input
|
|
105
|
-
id="email"
|
|
106
|
-
type="email"
|
|
107
|
-
{...register("email")}
|
|
108
|
-
className="border-input bg-background text-foreground focus:border-ring focus:ring-ring mt-1 block w-full rounded-md border px-3 py-2 text-sm shadow-sm focus:ring-1 focus:outline-none"
|
|
109
|
-
placeholder="jane@example.com"
|
|
110
|
-
/>
|
|
111
|
-
{errors.email && (
|
|
112
|
-
<p className="text-destructive mt-1 text-sm">
|
|
113
|
-
{errors.email.message}
|
|
114
|
-
</p>
|
|
115
|
-
)}
|
|
116
|
-
</div>
|
|
117
|
-
|
|
118
|
-
{/* Subject field */}
|
|
119
|
-
<div>
|
|
120
|
-
<label
|
|
121
|
-
htmlFor="subject"
|
|
122
|
-
className="text-foreground block text-sm font-medium"
|
|
123
|
-
>
|
|
124
|
-
Subject
|
|
125
|
-
</label>
|
|
126
|
-
<input
|
|
127
|
-
id="subject"
|
|
128
|
-
type="text"
|
|
129
|
-
{...register("subject")}
|
|
130
|
-
className="border-input bg-background text-foreground focus:border-ring focus:ring-ring mt-1 block w-full rounded-md border px-3 py-2 text-sm shadow-sm focus:ring-1 focus:outline-none"
|
|
131
|
-
placeholder="Order inquiry"
|
|
132
|
-
/>
|
|
133
|
-
{errors.subject && (
|
|
134
|
-
<p className="text-destructive mt-1 text-sm">
|
|
135
|
-
{errors.subject.message}
|
|
136
|
-
</p>
|
|
137
|
-
)}
|
|
138
|
-
</div>
|
|
139
|
-
|
|
140
|
-
{/* Message field */}
|
|
141
|
-
<div>
|
|
142
|
-
<label
|
|
143
|
-
htmlFor="message"
|
|
144
|
-
className="text-foreground block text-sm font-medium"
|
|
145
|
-
>
|
|
146
|
-
Message
|
|
147
|
-
</label>
|
|
148
|
-
<textarea
|
|
149
|
-
id="message"
|
|
150
|
-
rows={4}
|
|
151
|
-
{...register("message")}
|
|
152
|
-
className="border-input bg-background text-foreground focus:border-ring focus:ring-ring mt-1 block w-full rounded-md border px-3 py-2 text-sm shadow-sm focus:ring-1 focus:outline-none"
|
|
153
|
-
placeholder="Tell us more..."
|
|
154
|
-
/>
|
|
155
|
-
{errors.message && (
|
|
156
|
-
<p className="text-destructive mt-1 text-sm">
|
|
157
|
-
{errors.message.message}
|
|
158
|
-
</p>
|
|
159
|
-
)}
|
|
160
|
-
</div>
|
|
161
|
-
|
|
162
|
-
{/* Submit button */}
|
|
163
|
-
<div className="flex justify-end">
|
|
164
|
-
<button
|
|
165
|
-
type="submit"
|
|
166
|
-
disabled={isSubmitting}
|
|
167
|
-
className="bg-primary text-primary-foreground hover:bg-primary/90 focus:ring-ring focus:ring-offset-background rounded-md px-4 py-2 text-sm font-medium shadow-sm focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
168
|
-
>
|
|
169
|
-
{isSubmitting ? "Submitting..." : "Submit"}
|
|
170
|
-
</button>
|
|
171
|
-
</div>
|
|
172
|
-
</form>
|
|
173
|
-
)}
|
|
174
|
-
</div>
|
|
175
|
-
</div>
|
|
176
|
-
);
|
|
177
|
-
}
|