@fluid-app/fluid-cli-portal 0.1.32 → 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.
@@ -1,26 +0,0 @@
1
- /**
2
- * Code-defined navigation items.
3
- *
4
- * Synced to the Fluid OS API on `fluid deploy` with source: "code".
5
- * Position is derived from array order. Items without a slug are
6
- * treated as section headers.
7
- *
8
- * User-created navigation items (from the admin dashboard) are not
9
- * affected — only items with source: "code" are managed.
10
- *
11
- * IMPORTANT: Do not add import statements to this file. The Fluid CLI
12
- * reads this file without resolving dependencies, so it must be
13
- * self-contained static data only.
14
- */
15
- export const navigation = [
16
- {
17
- label: "Dashboard",
18
- slug: "dashboard",
19
- icon: "home",
20
- },
21
- {
22
- label: "MySite",
23
- slug: "my-site",
24
- icon: "globe",
25
- },
26
- ];
@@ -1,133 +0,0 @@
1
- import {
2
- TextWidget,
3
- ChartWidget,
4
- ToDoWidget,
5
- RecentActivityWidget,
6
- CalendarWidget,
7
- } from "@fluid-app/portal-sdk";
8
-
9
- /**
10
- * Sample chart data extracted as a module-level constant.
11
- *
12
- * The data is extracted as a constant to:
13
- * 1. Keep the component cleaner
14
- * 2. Allow reuse/testing if needed
15
- * 3. Make it clear the data is static
16
- */
17
- const MONTHLY_PERFORMANCE_DATA = [
18
- { name: "Jan", value: 4000 },
19
- { name: "Feb", value: 3000 },
20
- { name: "Mar", value: 5000 },
21
- { name: "Apr", value: 4500 },
22
- { name: "May", value: 6000 },
23
- { name: "Jun", value: 5500 },
24
- ];
25
-
26
- /**
27
- * Dashboard Screen
28
- *
29
- * This is the default landing screen for the portal.
30
- * It demonstrates using various widgets from portal-sdk:
31
- *
32
- * - TextWidget: Display text content with optional title
33
- * - ToDoWidget: Task list (uses useTodos hook)
34
- * - RecentActivityWidget: Activity feed (uses useActivities hook)
35
- * - ChartWidget: Bar, line, area, pie charts
36
- * - CalendarWidget: Calendar view (uses useCalendarEvents hook)
37
- *
38
- * These widgets fetch data from hooks that connect to your Fluid API.
39
- * In development, they show demo data. Configure fluid.config.ts
40
- * to connect to your Fluid instance.
41
- */
42
- export function DashboardScreen() {
43
- return (
44
- <div className="space-y-6">
45
- {/* Welcome section */}
46
- <TextWidget
47
- titleEnabled
48
- title="Welcome to Your Portal"
49
- description="This is your portal dashboard. Use widgets from @fluid-app/portal-sdk to build powerful interfaces for your team."
50
- padding={4}
51
- borderRadius="lg"
52
- />
53
-
54
- {/* Stats row - sample static data */}
55
- <div className="grid gap-6 md:grid-cols-3">
56
- <div className="bg-background rounded-lg p-4 shadow-sm">
57
- <p className="text-foreground text-3xl font-bold">$12,450</p>
58
- <p className="text-muted-foreground mt-1 text-sm">Total Sales</p>
59
- </div>
60
-
61
- <div className="bg-background rounded-lg p-4 shadow-sm">
62
- <p className="text-foreground text-3xl font-bold">24</p>
63
- <p className="text-muted-foreground mt-1 text-sm">Active Orders</p>
64
- </div>
65
-
66
- <div className="bg-background rounded-lg p-4 shadow-sm">
67
- <p className="text-foreground text-3xl font-bold">156</p>
68
- <p className="text-muted-foreground mt-1 text-sm">Customers</p>
69
- </div>
70
- </div>
71
-
72
- {/* Main content grid - Tasks and Activity */}
73
- <div className="grid gap-6 lg:grid-cols-2">
74
- {/* To-Do Widget - fetches tasks via useTodos hook */}
75
- <ToDoWidget
76
- titleEnabled
77
- titleText="Tasks"
78
- maxItems={5}
79
- padding={4}
80
- borderRadius="lg"
81
- />
82
-
83
- {/* Recent Activity Widget - fetches via useActivities hook */}
84
- <RecentActivityWidget
85
- titleEnabled
86
- titleText="Recent Activity"
87
- maxItemsToShow={5}
88
- padding={4}
89
- borderRadius="lg"
90
- />
91
- </div>
92
-
93
- {/* Performance chart - uses extracted constant data */}
94
- <ChartWidget
95
- titleEnabled
96
- title="Monthly Performance"
97
- chartType="bar"
98
- data={MONTHLY_PERFORMANCE_DATA}
99
- padding={4}
100
- borderRadius="lg"
101
- />
102
-
103
- {/* Calendar preview - uses useCalendarEvents hook */}
104
- <CalendarWidget
105
- titleEnabled
106
- titleText="Upcoming Events"
107
- padding={4}
108
- borderRadius="lg"
109
- />
110
-
111
- {/* Getting started tips */}
112
- <div className="grid gap-6 md:grid-cols-2">
113
- <TextWidget
114
- titleEnabled
115
- title="Customize Navigation"
116
- description="Edit portal.config.ts to add, remove, or reorder navigation items. Core screens (Messaging, Contacts) are built-in."
117
- padding={4}
118
- borderRadius="lg"
119
- background={{ type: "solid", color: "muted" }}
120
- />
121
-
122
- <TextWidget
123
- titleEnabled
124
- title="Connect Your Data"
125
- description="Configure fluid.config.ts with your Fluid API credentials. Widgets will automatically fetch real data from your account."
126
- padding={4}
127
- borderRadius="lg"
128
- background={{ type: "solid", color: "muted" }}
129
- />
130
- </div>
131
- </div>
132
- );
133
- }
@@ -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
- }