m9sh 0.2.1 → 0.2.2
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.
- checksums.yaml +4 -4
- data/.idea/hotcdn.iml +30 -0
- data/.mise.toml +2 -2
- data/app/assets/config/manifest.js +4 -0
- data/app/assets/images/icons/activity.svg +3 -0
- data/app/assets/images/icons/bell.svg +4 -0
- data/app/assets/images/icons/book.svg +4 -0
- data/app/assets/images/icons/chevron-down.svg +3 -0
- data/app/assets/images/icons/chevron-left.svg +3 -0
- data/app/assets/images/icons/chevron-right.svg +3 -0
- data/app/assets/images/icons/credit-card.svg +4 -0
- data/app/assets/images/icons/dollar-sign.svg +3 -0
- data/app/assets/images/icons/edit.svg +4 -0
- data/app/assets/images/icons/github.svg +3 -0
- data/app/assets/images/icons/home.svg +4 -0
- data/app/assets/images/icons/info.svg +5 -0
- data/app/assets/images/icons/layout.svg +6 -0
- data/app/assets/images/icons/logout.svg +5 -0
- data/app/assets/images/icons/menu.svg +5 -0
- data/app/assets/images/icons/moon.svg +3 -0
- data/app/assets/images/icons/paintbrush.svg +6 -0
- data/app/assets/images/icons/search.svg +4 -0
- data/app/assets/images/icons/settings.svg +4 -0
- data/app/assets/images/icons/sun.svg +11 -0
- data/app/assets/images/icons/user.svg +4 -0
- data/app/assets/images/icons/users.svg +5 -0
- data/app/assets/stylesheets/tailwind.css +1180 -0
- data/app/components/backdrop_component.rb +103 -0
- data/app/components/docs/code_block_component.rb +56 -0
- data/app/components/docs/component_api_component.rb +16 -0
- data/app/components/docs/component_examples_component.rb +16 -0
- data/app/components/docs/component_header_component.html.erb +8 -0
- data/app/components/docs/component_header_component.rb +14 -0
- data/app/components/docs/component_installation_component.html.erb +15 -0
- data/app/components/docs/component_installation_component.rb +13 -0
- data/app/components/docs/component_page_component.html.erb +9 -0
- data/app/components/docs/component_page_component.rb +19 -0
- data/app/components/docs/component_preview_component.rb +318 -0
- data/app/components/docs/component_usage_component.rb +18 -0
- data/app/components/docs/prop_table_component.rb +64 -0
- data/app/controllers/application_controller.rb +3 -0
- data/app/controllers/blocks_controller.rb +51 -0
- data/app/controllers/docs_controller.rb +162 -0
- data/app/controllers/showcase_controller.rb +42 -0
- data/app/helpers/blocks_helper.rb +343 -0
- data/app/helpers/docs_helper.rb +3807 -0
- data/app/helpers/m9sh/toast_helper.rb +46 -0
- data/app/helpers/m9sh_helper.rb +343 -0
- data/app/javascript/application.js +3 -0
- data/app/javascript/controllers/application.js +9 -0
- data/app/javascript/controllers/backdrop_controller.js +137 -0
- data/app/javascript/controllers/color_customizer_controller.js +569 -0
- data/app/javascript/controllers/color_theme_controller.js +120 -0
- data/app/javascript/controllers/docs/component_preview_controller.js +149 -0
- data/app/javascript/controllers/docs/copy_button_controller.js +20 -0
- data/app/javascript/controllers/index.js +6 -0
- data/app/javascript/controllers/theme_controller.js +23 -0
- data/app/views/blocks/_sidebar.html.erb +31 -0
- data/app/views/blocks/_toc.html.erb +29 -0
- data/app/views/blocks/examples/dashboard-01.html.erb +180 -0
- data/app/views/blocks/examples/dashboard-02.html.erb +190 -0
- data/app/views/blocks/examples/dashboard-03.html.erb +210 -0
- data/app/views/blocks/examples/settings-01.html.erb +220 -0
- data/app/views/blocks/examples/settings-02.html.erb +231 -0
- data/app/views/blocks/examples/settings-03.html.erb +340 -0
- data/app/views/blocks/index.html.erb +65 -0
- data/app/views/docs/_sidebar.html.erb +47 -0
- data/app/views/docs/_toc.html.erb +19 -0
- data/app/views/docs/about.html.erb +68 -0
- data/app/views/docs/components/accordion.html.erb +196 -0
- data/app/views/docs/components/alert.html.erb +272 -0
- data/app/views/docs/components/alert_dialog.html.erb +232 -0
- data/app/views/docs/components/avatar.html.erb +207 -0
- data/app/views/docs/components/badge.html.erb +145 -0
- data/app/views/docs/components/breadcrumb.html.erb +264 -0
- data/app/views/docs/components/button.html.erb +229 -0
- data/app/views/docs/components/card.html.erb +378 -0
- data/app/views/docs/components/checkbox.html.erb +212 -0
- data/app/views/docs/components/collapsible.html.erb +252 -0
- data/app/views/docs/components/dialog.html.erb +323 -0
- data/app/views/docs/components/dropdown_menu.html.erb +289 -0
- data/app/views/docs/components/hover_card.html.erb +220 -0
- data/app/views/docs/components/input.html.erb +254 -0
- data/app/views/docs/components/label.html.erb +128 -0
- data/app/views/docs/components/main.html.erb +352 -0
- data/app/views/docs/components/navbar.html.erb +394 -0
- data/app/views/docs/components/navigation_menu.html.erb +226 -0
- data/app/views/docs/components/popover.html.erb +267 -0
- data/app/views/docs/components/progress.html.erb +107 -0
- data/app/views/docs/components/radio_group.html.erb +209 -0
- data/app/views/docs/components/select.html.erb +260 -0
- data/app/views/docs/components/separator.html.erb +162 -0
- data/app/views/docs/components/sheet.html.erb +270 -0
- data/app/views/docs/components/sidebar.html.erb +597 -0
- data/app/views/docs/components/skeleton.html.erb +150 -0
- data/app/views/docs/components/slider.html.erb +218 -0
- data/app/views/docs/components/spinner.html.erb +132 -0
- data/app/views/docs/components/switch.html.erb +148 -0
- data/app/views/docs/components/table.html.erb +259 -0
- data/app/views/docs/components/tabs.html.erb +225 -0
- data/app/views/docs/components/textarea.html.erb +239 -0
- data/app/views/docs/components/theme_toggle.html.erb +135 -0
- data/app/views/docs/components/toast.html.erb +205 -0
- data/app/views/docs/components/toaster.html.erb +227 -0
- data/app/views/docs/components/toggle.html.erb +154 -0
- data/app/views/docs/components/tooltip.html.erb +216 -0
- data/app/views/docs/components/typography.html.erb +180 -0
- data/app/views/docs/index.html.erb +143 -0
- data/app/views/docs/installation.html.erb +155 -0
- data/app/views/docs/simple_test.html.erb +13 -0
- data/app/views/docs/test_accordion.html.erb +14 -0
- data/app/views/docs/usage.html.erb +272 -0
- data/app/views/layouts/application.html.erb +107 -0
- data/app/views/layouts/backdrop.html.erb +77 -0
- data/app/views/shared/_app_navbar.html.erb +240 -0
- data/app/views/shared/_navbar.html.erb +69 -0
- data/app/views/showcase/v2/_components_grid.html.erb +38 -0
- data/app/views/showcase/v2/_features.html.erb +59 -0
- data/app/views/showcase/v2/_forms.html.erb +195 -0
- data/app/views/showcase/v2/_hero.html.erb +55 -0
- data/app/views/showcase/v2/_metrics.html.erb +107 -0
- data/app/views/showcase/v2.html.erb +18 -0
- data/lib/m9sh/version.rb +1 -1
- data/m9sh.gemspec +1 -1
- metadata +120 -1
@@ -0,0 +1,210 @@
|
|
1
|
+
<% content_for :title, "Dashboard 03 - Blocks" %>
|
2
|
+
|
3
|
+
<!-- Page Header -->
|
4
|
+
<div class="space-y-2 mb-8">
|
5
|
+
<h1 class="text-3xl font-bold tracking-tight">Dashboard 03</h1>
|
6
|
+
<p class="text-muted-foreground">
|
7
|
+
An e-commerce dashboard with orders, inventory, and customer insights. Perfect for online stores and marketplace platforms.
|
8
|
+
</p>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<!-- Dashboard Preview -->
|
12
|
+
<% dashboard_html = capture do %>
|
13
|
+
<div class="w-full space-y-6">
|
14
|
+
<!-- Quick Stats -->
|
15
|
+
<div class="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
16
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
17
|
+
<% card.with_body do %>
|
18
|
+
<div class="flex items-center justify-between">
|
19
|
+
<div>
|
20
|
+
<p class="text-sm font-medium text-muted-foreground">Total Sales</p>
|
21
|
+
<p class="text-2xl font-bold mt-1">$54,239</p>
|
22
|
+
<p class="text-xs text-muted-foreground mt-1">+18.2% from last week</p>
|
23
|
+
</div>
|
24
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="h-10 w-10 text-muted-foreground">
|
25
|
+
<path d="M16 8v10M12 11v7M8 14v4"/>
|
26
|
+
<path d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
|
27
|
+
</svg>
|
28
|
+
</div>
|
29
|
+
<% end %>
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
33
|
+
<% card.with_body do %>
|
34
|
+
<div class="flex items-center justify-between">
|
35
|
+
<div>
|
36
|
+
<p class="text-sm font-medium text-muted-foreground">Orders</p>
|
37
|
+
<p class="text-2xl font-bold mt-1">342</p>
|
38
|
+
<p class="text-xs text-muted-foreground mt-1">+23 new today</p>
|
39
|
+
</div>
|
40
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="h-10 w-10 text-muted-foreground">
|
41
|
+
<path d="M16 16v-4"/>
|
42
|
+
<path d="M8 16V8"/>
|
43
|
+
<path d="M12 16v-1"/>
|
44
|
+
<rect x="3" y="12" width="18" height="8" rx="1"/>
|
45
|
+
<path d="M7 12v-4a5 5 0 0 1 10 0v4"/>
|
46
|
+
</svg>
|
47
|
+
</div>
|
48
|
+
<% end %>
|
49
|
+
<% end %>
|
50
|
+
|
51
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
52
|
+
<% card.with_body do %>
|
53
|
+
<div class="flex items-center justify-between">
|
54
|
+
<div>
|
55
|
+
<p class="text-sm font-medium text-muted-foreground">Customers</p>
|
56
|
+
<p class="text-2xl font-bold mt-1">1,429</p>
|
57
|
+
<p class="text-xs text-muted-foreground mt-1">+89 this month</p>
|
58
|
+
</div>
|
59
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="h-10 w-10 text-muted-foreground">
|
60
|
+
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
|
61
|
+
<circle cx="9" cy="7" r="4"/>
|
62
|
+
<path d="M22 21v-2a4 4 0 0 0-3-3.87"/>
|
63
|
+
<path d="M16 3.13a4 4 0 0 1 0 7.75"/>
|
64
|
+
</svg>
|
65
|
+
</div>
|
66
|
+
<% end %>
|
67
|
+
<% end %>
|
68
|
+
|
69
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
70
|
+
<% card.with_body do %>
|
71
|
+
<div class="flex items-center justify-between">
|
72
|
+
<div>
|
73
|
+
<p class="text-sm font-medium text-muted-foreground">Conversion</p>
|
74
|
+
<p class="text-2xl font-bold mt-1">3.2%</p>
|
75
|
+
<p class="text-xs text-muted-foreground mt-1">+0.4% from last week</p>
|
76
|
+
</div>
|
77
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="h-10 w-10 text-muted-foreground">
|
78
|
+
<path d="M12 2v20"/>
|
79
|
+
<path d="m15 5-3-3-3 3"/>
|
80
|
+
<path d="m9 19 3 3 3-3"/>
|
81
|
+
</svg>
|
82
|
+
</div>
|
83
|
+
<% end %>
|
84
|
+
<% end %>
|
85
|
+
</div>
|
86
|
+
|
87
|
+
<!-- Recent Orders and Top Products -->
|
88
|
+
<div class="grid gap-4 grid-cols-1 lg:grid-cols-2">
|
89
|
+
<!-- Recent Orders Table -->
|
90
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
91
|
+
<% card.with_header do |header| %>
|
92
|
+
<% header.with_title do %>
|
93
|
+
Recent Orders
|
94
|
+
<% end %>
|
95
|
+
<% header.with_description do %>
|
96
|
+
Latest orders from your store
|
97
|
+
<% end %>
|
98
|
+
<% end %>
|
99
|
+
<% card.with_body do %>
|
100
|
+
<%= render M9sh::TableComponent.new do |table| %>
|
101
|
+
<% table.with_header do %>
|
102
|
+
<tr>
|
103
|
+
<th>Order</th>
|
104
|
+
<th>Customer</th>
|
105
|
+
<th>Amount</th>
|
106
|
+
<th>Status</th>
|
107
|
+
</tr>
|
108
|
+
<% end %>
|
109
|
+
<% table.with_body do %>
|
110
|
+
<% [
|
111
|
+
{ order: "#3210", customer: "John Doe", amount: "$129.99", status: "Delivered", status_variant: :default },
|
112
|
+
{ order: "#3209", customer: "Jane Smith", amount: "$89.50", status: "Processing", status_variant: :secondary },
|
113
|
+
{ order: "#3208", customer: "Bob Johnson", amount: "$245.00", status: "Shipped", status_variant: :outline },
|
114
|
+
{ order: "#3207", customer: "Alice Brown", amount: "$67.25", status: "Delivered", status_variant: :default },
|
115
|
+
{ order: "#3206", customer: "Charlie Wilson", amount: "$199.99", status: "Cancelled", status_variant: :destructive }
|
116
|
+
].each do |order| %>
|
117
|
+
<tr>
|
118
|
+
<td class="font-medium"><%= order[:order] %></td>
|
119
|
+
<td><%= order[:customer] %></td>
|
120
|
+
<td><%= order[:amount] %></td>
|
121
|
+
<td>
|
122
|
+
<%= render M9sh::BadgeComponent.new(variant: order[:status_variant], class: "text-xs") do %>
|
123
|
+
<%= order[:status] %>
|
124
|
+
<% end %>
|
125
|
+
</td>
|
126
|
+
</tr>
|
127
|
+
<% end %>
|
128
|
+
<% end %>
|
129
|
+
<% end %>
|
130
|
+
<% end %>
|
131
|
+
<% end %>
|
132
|
+
|
133
|
+
<!-- Top Products -->
|
134
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
135
|
+
<% card.with_header do |header| %>
|
136
|
+
<% header.with_title do %>
|
137
|
+
Top Products
|
138
|
+
<% end %>
|
139
|
+
<% header.with_description do %>
|
140
|
+
Best selling items this month
|
141
|
+
<% end %>
|
142
|
+
<% end %>
|
143
|
+
<% card.with_body do %>
|
144
|
+
<div class="space-y-4">
|
145
|
+
<% [
|
146
|
+
{ product: "Wireless Headphones", sales: 342, revenue: "$34,200", trend: "+12%" },
|
147
|
+
{ product: "Smart Watch Pro", sales: 289, revenue: "$57,800", trend: "+8%" },
|
148
|
+
{ product: "Laptop Stand", sales: 234, revenue: "$9,360", trend: "+15%" },
|
149
|
+
{ product: "USB-C Hub", sales: 198, revenue: "$11,880", trend: "+5%" },
|
150
|
+
{ product: "Mechanical Keyboard", sales: 156, revenue: "$18,720", trend: "+20%" }
|
151
|
+
].each do |product| %>
|
152
|
+
<div class="flex items-center justify-between pb-4 border-b border-border last:border-0 last:pb-0">
|
153
|
+
<div class="flex-1">
|
154
|
+
<p class="text-sm font-medium"><%= product[:product] %></p>
|
155
|
+
<div class="flex items-center gap-2 mt-1">
|
156
|
+
<p class="text-xs text-muted-foreground"><%= product[:sales] %> sold</p>
|
157
|
+
<span class="text-xs text-muted-foreground">•</span>
|
158
|
+
<p class="text-xs text-muted-foreground"><%= product[:revenue] %></p>
|
159
|
+
</div>
|
160
|
+
</div>
|
161
|
+
<%= render M9sh::BadgeComponent.new(variant: :default, class: "text-xs") do %>
|
162
|
+
<%= product[:trend] %>
|
163
|
+
<% end %>
|
164
|
+
</div>
|
165
|
+
<% end %>
|
166
|
+
</div>
|
167
|
+
<% end %>
|
168
|
+
<% end %>
|
169
|
+
</div>
|
170
|
+
</div>
|
171
|
+
<% end %>
|
172
|
+
|
173
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
174
|
+
title: "E-Commerce Dashboard",
|
175
|
+
preview_content: dashboard_html,
|
176
|
+
code: dashboard_03_code,
|
177
|
+
ai_command: dashboard_03_code
|
178
|
+
) %>
|
179
|
+
|
180
|
+
<!-- Usage Section -->
|
181
|
+
<div class="mt-12 space-y-4">
|
182
|
+
<h2 class="text-2xl font-semibold tracking-tight">Usage</h2>
|
183
|
+
<p class="text-muted-foreground leading-relaxed">
|
184
|
+
An e-commerce dashboard displaying orders, customer data, and product performance. Ideal for online stores and marketplace platforms.
|
185
|
+
</p>
|
186
|
+
|
187
|
+
<%= render M9sh::CardComponent.new(class: "mt-6") do |card| %>
|
188
|
+
<% card.with_header do |header| %>
|
189
|
+
<% header.with_title do %>
|
190
|
+
Required Components
|
191
|
+
<% end %>
|
192
|
+
<% header.with_description do %>
|
193
|
+
Make sure these components are installed in your project
|
194
|
+
<% end %>
|
195
|
+
<% end %>
|
196
|
+
<% card.with_body do %>
|
197
|
+
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
198
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
199
|
+
CardComponent
|
200
|
+
<% end %>
|
201
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
202
|
+
TableComponent
|
203
|
+
<% end %>
|
204
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
205
|
+
BadgeComponent
|
206
|
+
<% end %>
|
207
|
+
</div>
|
208
|
+
<% end %>
|
209
|
+
<% end %>
|
210
|
+
</div>
|
@@ -0,0 +1,220 @@
|
|
1
|
+
<% content_for :title, "Settings 01 - Blocks" %>
|
2
|
+
|
3
|
+
<!-- Page Header -->
|
4
|
+
<div class="space-y-2 mb-8">
|
5
|
+
<h1 class="text-3xl font-bold tracking-tight">Settings 01</h1>
|
6
|
+
<p class="text-muted-foreground">
|
7
|
+
Profile and account settings page with form inputs, avatar management, and user preferences. Perfect for user account management interfaces.
|
8
|
+
</p>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<!-- Settings Preview -->
|
12
|
+
<% settings_html = capture do %>
|
13
|
+
<div class="w-full">
|
14
|
+
<div class="max-w-3xl mx-auto space-y-8">
|
15
|
+
<%# CODE_START %>
|
16
|
+
<!-- Page Header -->
|
17
|
+
<div class="space-y-1">
|
18
|
+
<h2 class="text-2xl font-semibold tracking-tight">Settings</h2>
|
19
|
+
<p class="text-sm text-muted-foreground">
|
20
|
+
Manage your account settings and preferences.
|
21
|
+
</p>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<%= render M9sh::SeparatorComponent.new(class: "my-6") %>
|
25
|
+
|
26
|
+
<!-- Profile Section -->
|
27
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
28
|
+
<% card.with_header do |header| %>
|
29
|
+
<% header.with_title { "Profile" } %>
|
30
|
+
<% header.with_description { "Update your personal information and profile picture." } %>
|
31
|
+
<% end %>
|
32
|
+
<% card.with_body do %>
|
33
|
+
<div class="space-y-6">
|
34
|
+
<!-- Avatar Upload -->
|
35
|
+
<div class="flex items-center gap-4">
|
36
|
+
<%= render M9sh::AvatarComponent.new(fallback: "JD", class: "h-20 w-20 text-lg") %>
|
37
|
+
<div class="space-y-2">
|
38
|
+
<%= render M9sh::ButtonComponent.new(variant: :outline, size: :sm) do %>
|
39
|
+
Change Avatar
|
40
|
+
<% end %>
|
41
|
+
<p class="text-xs text-muted-foreground">JPG, PNG or GIF. Max 2MB.</p>
|
42
|
+
</div>
|
43
|
+
</div>
|
44
|
+
|
45
|
+
<!-- Name Fields -->
|
46
|
+
<div class="grid gap-4 md:grid-cols-2">
|
47
|
+
<div class="space-y-2">
|
48
|
+
<%= render M9sh::LabelComponent.new(for: "first-name") { "First Name" } %>
|
49
|
+
<%= render M9sh::InputComponent.new(id: "first-name", placeholder: "John", value: "John") %>
|
50
|
+
</div>
|
51
|
+
<div class="space-y-2">
|
52
|
+
<%= render M9sh::LabelComponent.new(for: "last-name") { "Last Name" } %>
|
53
|
+
<%= render M9sh::InputComponent.new(id: "last-name", placeholder: "Doe", value: "Doe") %>
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
|
57
|
+
<!-- Email -->
|
58
|
+
<div class="space-y-2">
|
59
|
+
<%= render M9sh::LabelComponent.new(for: "email") { "Email" } %>
|
60
|
+
<%= render M9sh::InputComponent.new(id: "email", type: :email, placeholder: "john.doe@example.com", value: "john.doe@example.com") %>
|
61
|
+
<p class="text-xs text-muted-foreground">We'll never share your email with anyone else.</p>
|
62
|
+
</div>
|
63
|
+
|
64
|
+
<!-- Bio -->
|
65
|
+
<div class="space-y-2">
|
66
|
+
<%= render M9sh::LabelComponent.new(for: "bio") { "Bio" } %>
|
67
|
+
<%= render M9sh::TextareaComponent.new(id: "bio", placeholder: "Tell us about yourself...", rows: 4) %>
|
68
|
+
<p class="text-xs text-muted-foreground">Brief description for your profile. Max 500 characters.</p>
|
69
|
+
</div>
|
70
|
+
</div>
|
71
|
+
<% end %>
|
72
|
+
<% card.with_footer do %>
|
73
|
+
<div class="flex justify-end gap-2">
|
74
|
+
<%= render M9sh::ButtonComponent.new(variant: :outline) do %>
|
75
|
+
Cancel
|
76
|
+
<% end %>
|
77
|
+
<%= render M9sh::ButtonComponent.new do %>
|
78
|
+
Save Changes
|
79
|
+
<% end %>
|
80
|
+
</div>
|
81
|
+
<% end %>
|
82
|
+
<% end %>
|
83
|
+
|
84
|
+
<!-- Account Security -->
|
85
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
86
|
+
<% card.with_header do |header| %>
|
87
|
+
<% header.with_title { "Account Security" } %>
|
88
|
+
<% header.with_description { "Update your password and security settings." } %>
|
89
|
+
<% end %>
|
90
|
+
<% card.with_body do %>
|
91
|
+
<div class="space-y-4">
|
92
|
+
<div class="space-y-2">
|
93
|
+
<%= render M9sh::LabelComponent.new(for: "current-password") { "Current Password" } %>
|
94
|
+
<%= render M9sh::InputComponent.new(id: "current-password", type: :password, placeholder: "Enter current password") %>
|
95
|
+
</div>
|
96
|
+
<div class="space-y-2">
|
97
|
+
<%= render M9sh::LabelComponent.new(for: "new-password") { "New Password" } %>
|
98
|
+
<%= render M9sh::InputComponent.new(id: "new-password", type: :password, placeholder: "Enter new password") %>
|
99
|
+
</div>
|
100
|
+
<div class="space-y-2">
|
101
|
+
<%= render M9sh::LabelComponent.new(for: "confirm-password") { "Confirm Password" } %>
|
102
|
+
<%= render M9sh::InputComponent.new(id: "confirm-password", type: :password, placeholder: "Confirm new password") %>
|
103
|
+
</div>
|
104
|
+
</div>
|
105
|
+
<% end %>
|
106
|
+
<% card.with_footer do %>
|
107
|
+
<%= render M9sh::ButtonComponent.new do %>
|
108
|
+
Update Password
|
109
|
+
<% end %>
|
110
|
+
<% end %>
|
111
|
+
<% end %>
|
112
|
+
|
113
|
+
<!-- Preferences -->
|
114
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
115
|
+
<% card.with_header do |header| %>
|
116
|
+
<% header.with_title { "Preferences" } %>
|
117
|
+
<% header.with_description { "Manage your notification and communication preferences." } %>
|
118
|
+
<% end %>
|
119
|
+
<% card.with_body do %>
|
120
|
+
<div class="space-y-4">
|
121
|
+
<% [
|
122
|
+
{ id: "marketing", label: "Marketing Emails", description: "Receive emails about new products and features." },
|
123
|
+
{ id: "updates", label: "Product Updates", description: "Get notified about product updates and improvements." },
|
124
|
+
{ id: "social", label: "Social Notifications", description: "Receive notifications about mentions and comments." },
|
125
|
+
{ id: "security", label: "Security Alerts", description: "Important security notifications about your account." }
|
126
|
+
].each do |pref| %>
|
127
|
+
<div class="flex items-center justify-between space-x-2 py-2">
|
128
|
+
<div class="space-y-0.5 flex-1">
|
129
|
+
<%= render M9sh::LabelComponent.new(for: pref[:id], class: "font-medium cursor-pointer") { pref[:label] } %>
|
130
|
+
<p class="text-sm text-muted-foreground"><%= pref[:description] %></p>
|
131
|
+
</div>
|
132
|
+
<%= render M9sh::SwitchComponent.new(id: pref[:id], checked: pref[:id] == "security") %>
|
133
|
+
</div>
|
134
|
+
<%= render M9sh::SeparatorComponent.new if pref != { id: "security", label: "Security Alerts", description: "Important security notifications about your account." } %>
|
135
|
+
<% end %>
|
136
|
+
</div>
|
137
|
+
<% end %>
|
138
|
+
<% end %>
|
139
|
+
|
140
|
+
<!-- Danger Zone -->
|
141
|
+
<%= render M9sh::CardComponent.new(class: "border-destructive") do |card| %>
|
142
|
+
<% card.with_header do |header| %>
|
143
|
+
<% header.with_title(class: "text-destructive") { "Danger Zone" } %>
|
144
|
+
<% header.with_description { "Irreversible actions that affect your account." } %>
|
145
|
+
<% end %>
|
146
|
+
<% card.with_body do %>
|
147
|
+
<div class="space-y-4">
|
148
|
+
<%= render M9sh::AlertComponent.new(variant: :destructive) do %>
|
149
|
+
<div class="space-y-2">
|
150
|
+
<p class="font-medium">Delete Account</p>
|
151
|
+
<p class="text-sm">Once you delete your account, there is no going back. Please be certain.</p>
|
152
|
+
</div>
|
153
|
+
<% end %>
|
154
|
+
<%= render M9sh::ButtonComponent.new(variant: :destructive) do %>
|
155
|
+
Delete Account
|
156
|
+
<% end %>
|
157
|
+
</div>
|
158
|
+
<% end %>
|
159
|
+
<% end %>
|
160
|
+
<%# CODE_END %>
|
161
|
+
</div>
|
162
|
+
</div>
|
163
|
+
<% end %>
|
164
|
+
|
165
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
166
|
+
title: "Profile & Account Settings",
|
167
|
+
preview_content: settings_html,
|
168
|
+
code: extract_block_code("<%# CODE_START %>", "<%# CODE_END %>"),
|
169
|
+
ai_command: extract_block_code("<%# CODE_START %>", "<%# CODE_END %>")
|
170
|
+
) %>
|
171
|
+
|
172
|
+
<!-- Usage Section -->
|
173
|
+
<div class="mt-12 space-y-4">
|
174
|
+
<h2 class="text-2xl font-semibold tracking-tight">Usage</h2>
|
175
|
+
<p class="text-muted-foreground leading-relaxed">
|
176
|
+
A comprehensive settings page for profile and account management. Features form inputs, avatar management, password updates, and user preferences with switches.
|
177
|
+
</p>
|
178
|
+
|
179
|
+
<%= render M9sh::CardComponent.new(class: "mt-6") do |card| %>
|
180
|
+
<% card.with_header do |header| %>
|
181
|
+
<% header.with_title do %>
|
182
|
+
Required Components
|
183
|
+
<% end %>
|
184
|
+
<% header.with_description do %>
|
185
|
+
Make sure these components are installed in your project
|
186
|
+
<% end %>
|
187
|
+
<% end %>
|
188
|
+
<% card.with_body do %>
|
189
|
+
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
190
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
191
|
+
CardComponent
|
192
|
+
<% end %>
|
193
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
194
|
+
InputComponent
|
195
|
+
<% end %>
|
196
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
197
|
+
LabelComponent
|
198
|
+
<% end %>
|
199
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
200
|
+
TextareaComponent
|
201
|
+
<% end %>
|
202
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
203
|
+
ButtonComponent
|
204
|
+
<% end %>
|
205
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
206
|
+
AvatarComponent
|
207
|
+
<% end %>
|
208
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
209
|
+
SwitchComponent
|
210
|
+
<% end %>
|
211
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
212
|
+
AlertComponent
|
213
|
+
<% end %>
|
214
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
215
|
+
SeparatorComponent
|
216
|
+
<% end %>
|
217
|
+
</div>
|
218
|
+
<% end %>
|
219
|
+
<% end %>
|
220
|
+
</div>
|
@@ -0,0 +1,231 @@
|
|
1
|
+
<% content_for :title, "Settings 02 - Blocks" %>
|
2
|
+
|
3
|
+
<!-- Page Header -->
|
4
|
+
<div class="space-y-2 mb-8">
|
5
|
+
<h1 class="text-3xl font-bold tracking-tight">Settings 02</h1>
|
6
|
+
<p class="text-muted-foreground">
|
7
|
+
Appearance and display settings page with theme selection, font options, and layout preferences. Perfect for customizable user interfaces.
|
8
|
+
</p>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<!-- Settings Preview -->
|
12
|
+
<% settings_html = capture do %>
|
13
|
+
<div class="w-full">
|
14
|
+
<div class="max-w-3xl mx-auto space-y-8">
|
15
|
+
<%# CODE_START %>
|
16
|
+
<!-- Page Header -->
|
17
|
+
<div class="space-y-1">
|
18
|
+
<h2 class="text-2xl font-semibold tracking-tight">Appearance</h2>
|
19
|
+
<p class="text-sm text-muted-foreground">
|
20
|
+
Customize how the application looks and feels.
|
21
|
+
</p>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<%= render M9sh::SeparatorComponent.new(class: "my-6") %>
|
25
|
+
|
26
|
+
<!-- Theme Selection -->
|
27
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
28
|
+
<% card.with_header do |header| %>
|
29
|
+
<% header.with_title { "Theme" } %>
|
30
|
+
<% header.with_description { "Select your preferred color theme." } %>
|
31
|
+
<% end %>
|
32
|
+
<% card.with_body do %>
|
33
|
+
<%= render M9sh::RadioGroupComponent.new(name: "theme", default_value: "light") do |group| %>
|
34
|
+
<div class="grid gap-4 md:grid-cols-3">
|
35
|
+
<% [
|
36
|
+
{ value: "light", label: "Light", description: "Clean and bright interface" },
|
37
|
+
{ value: "dark", label: "Dark", description: "Easy on the eyes" },
|
38
|
+
{ value: "system", label: "System", description: "Use system preference" }
|
39
|
+
].each do |theme| %>
|
40
|
+
<label class="flex flex-col space-y-2 cursor-pointer border rounded-lg p-4 hover:bg-accent transition-colors">
|
41
|
+
<%= render group.item(value: theme[:value], id: "theme-#{theme[:value]}") %>
|
42
|
+
<div class="space-y-1">
|
43
|
+
<p class="font-medium leading-none"><%= theme[:label] %></p>
|
44
|
+
<p class="text-sm text-muted-foreground"><%= theme[:description] %></p>
|
45
|
+
</div>
|
46
|
+
</label>
|
47
|
+
<% end %>
|
48
|
+
</div>
|
49
|
+
<% end %>
|
50
|
+
<% end %>
|
51
|
+
<% end %>
|
52
|
+
|
53
|
+
<!-- Font Size -->
|
54
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
55
|
+
<% card.with_header do |header| %>
|
56
|
+
<% header.with_title { "Font Size" } %>
|
57
|
+
<% header.with_description { "Adjust the text size throughout the application." } %>
|
58
|
+
<% end %>
|
59
|
+
<% card.with_body do %>
|
60
|
+
<div class="space-y-4">
|
61
|
+
<div class="space-y-2">
|
62
|
+
<%= render M9sh::LabelComponent.new(for: "font-size") { "Text Size" } %>
|
63
|
+
<%= render M9sh::SelectComponent.new(id: "font-size") do %>
|
64
|
+
<option value="small">Small</option>
|
65
|
+
<option value="medium" selected>Medium (Default)</option>
|
66
|
+
<option value="large">Large</option>
|
67
|
+
<option value="x-large">Extra Large</option>
|
68
|
+
<% end %>
|
69
|
+
</div>
|
70
|
+
<div class="border rounded-lg p-4 space-y-2">
|
71
|
+
<p class="text-sm font-medium">Preview</p>
|
72
|
+
<p class="text-muted-foreground">This is how your text will appear with the selected font size.</p>
|
73
|
+
</div>
|
74
|
+
</div>
|
75
|
+
<% end %>
|
76
|
+
<% end %>
|
77
|
+
|
78
|
+
<!-- Layout Options -->
|
79
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
80
|
+
<% card.with_header do |header| %>
|
81
|
+
<% header.with_title { "Layout" } %>
|
82
|
+
<% header.with_description { "Customize the layout and spacing of the interface." } %>
|
83
|
+
<% end %>
|
84
|
+
<% card.with_body do %>
|
85
|
+
<div class="space-y-4">
|
86
|
+
<% [
|
87
|
+
{ id: "compact", label: "Compact Mode", description: "Reduce spacing between elements for a denser layout." },
|
88
|
+
{ id: "sidebar-left", label: "Left Sidebar", description: "Display sidebar on the left side (default).", checked: true },
|
89
|
+
{ id: "animations", label: "Enable Animations", description: "Show smooth transitions and animations.", checked: true }
|
90
|
+
].each do |option| %>
|
91
|
+
<div class="flex items-start space-x-3 py-2">
|
92
|
+
<%= render M9sh::CheckboxComponent.new(
|
93
|
+
id: option[:id],
|
94
|
+
checked: option[:checked] || false
|
95
|
+
) %>
|
96
|
+
<div class="space-y-1 leading-none">
|
97
|
+
<%= render M9sh::LabelComponent.new(for: option[:id], class: "font-medium cursor-pointer") { option[:label] } %>
|
98
|
+
<p class="text-sm text-muted-foreground"><%= option[:description] %></p>
|
99
|
+
</div>
|
100
|
+
</div>
|
101
|
+
<% end %>
|
102
|
+
</div>
|
103
|
+
<% end %>
|
104
|
+
<% card.with_footer do %>
|
105
|
+
<div class="flex justify-end gap-2">
|
106
|
+
<%= render M9sh::ButtonComponent.new(variant: :outline) do %>
|
107
|
+
Reset to Defaults
|
108
|
+
<% end %>
|
109
|
+
<%= render M9sh::ButtonComponent.new do %>
|
110
|
+
Save Preferences
|
111
|
+
<% end %>
|
112
|
+
</div>
|
113
|
+
<% end %>
|
114
|
+
<% end %>
|
115
|
+
|
116
|
+
<!-- Accessibility -->
|
117
|
+
<%= render M9sh::CardComponent.new do |card| %>
|
118
|
+
<% card.with_header do |header| %>
|
119
|
+
<% header.with_title { "Accessibility" } %>
|
120
|
+
<% header.with_description { "Features to improve accessibility and usability." } %>
|
121
|
+
<% end %>
|
122
|
+
<% card.with_body do %>
|
123
|
+
<div class="space-y-4">
|
124
|
+
<% [
|
125
|
+
{ id: "high-contrast", label: "High Contrast", description: "Increase contrast between text and background." },
|
126
|
+
{ id: "reduce-motion", label: "Reduce Motion", description: "Minimize animations and transitions." },
|
127
|
+
{ id: "focus-indicators", label: "Enhanced Focus", description: "Show prominent focus indicators for keyboard navigation.", checked: true },
|
128
|
+
{ id: "screen-reader", label: "Screen Reader Optimized", description: "Optimize for screen reader compatibility.", checked: true }
|
129
|
+
].each do |feature| %>
|
130
|
+
<div class="flex items-center justify-between space-x-2 py-2">
|
131
|
+
<div class="space-y-0.5 flex-1">
|
132
|
+
<%= render M9sh::LabelComponent.new(for: feature[:id], class: "font-medium cursor-pointer") { feature[:label] } %>
|
133
|
+
<p class="text-sm text-muted-foreground"><%= feature[:description] %></p>
|
134
|
+
</div>
|
135
|
+
<%= render M9sh::SwitchComponent.new(id: feature[:id], checked: feature[:checked] || false) %>
|
136
|
+
</div>
|
137
|
+
<%= render M9sh::SeparatorComponent.new unless feature[:id] == "screen-reader" %>
|
138
|
+
<% end %>
|
139
|
+
</div>
|
140
|
+
<% end %>
|
141
|
+
<% end %>
|
142
|
+
|
143
|
+
<!-- Preview Card -->
|
144
|
+
<%= render M9sh::CardComponent.new(class: "bg-accent/50") do |card| %>
|
145
|
+
<% card.with_header do |header| %>
|
146
|
+
<% header.with_title { "Preview" } %>
|
147
|
+
<% header.with_description { "See how your settings affect the interface." } %>
|
148
|
+
<% end %>
|
149
|
+
<% card.with_body do %>
|
150
|
+
<div class="space-y-3 p-4 border rounded-lg bg-background">
|
151
|
+
<div class="flex items-center justify-between">
|
152
|
+
<h3 class="font-semibold">Example Component</h3>
|
153
|
+
<%= render M9sh::BadgeComponent.new do %>
|
154
|
+
New
|
155
|
+
<% end %>
|
156
|
+
</div>
|
157
|
+
<p class="text-sm text-muted-foreground">
|
158
|
+
This preview shows how your selected appearance settings will affect the interface elements.
|
159
|
+
</p>
|
160
|
+
<div class="flex gap-2">
|
161
|
+
<%= render M9sh::ButtonComponent.new(size: :sm) do %>
|
162
|
+
Primary
|
163
|
+
<% end %>
|
164
|
+
<%= render M9sh::ButtonComponent.new(variant: :outline, size: :sm) do %>
|
165
|
+
Secondary
|
166
|
+
<% end %>
|
167
|
+
</div>
|
168
|
+
</div>
|
169
|
+
<% end %>
|
170
|
+
<% end %>
|
171
|
+
<%# CODE_END %>
|
172
|
+
</div>
|
173
|
+
</div>
|
174
|
+
<% end %>
|
175
|
+
|
176
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
177
|
+
title: "Appearance Settings",
|
178
|
+
preview_content: settings_html,
|
179
|
+
code: extract_block_code("<%# CODE_START %>", "<%# CODE_END %>"),
|
180
|
+
ai_command: extract_block_code("<%# CODE_START %>", "<%# CODE_END %>")
|
181
|
+
) %>
|
182
|
+
|
183
|
+
<!-- Usage Section -->
|
184
|
+
<div class="mt-12 space-y-4">
|
185
|
+
<h2 class="text-2xl font-semibold tracking-tight">Usage</h2>
|
186
|
+
<p class="text-muted-foreground leading-relaxed">
|
187
|
+
An appearance and display settings page with theme selection, font options, layout preferences, and accessibility features. Perfect for applications that offer extensive customization.
|
188
|
+
</p>
|
189
|
+
|
190
|
+
<%= render M9sh::CardComponent.new(class: "mt-6") do |card| %>
|
191
|
+
<% card.with_header do |header| %>
|
192
|
+
<% header.with_title do %>
|
193
|
+
Required Components
|
194
|
+
<% end %>
|
195
|
+
<% header.with_description do %>
|
196
|
+
Make sure these components are installed in your project
|
197
|
+
<% end %>
|
198
|
+
<% end %>
|
199
|
+
<% card.with_body do %>
|
200
|
+
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
201
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
202
|
+
CardComponent
|
203
|
+
<% end %>
|
204
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
205
|
+
RadioGroupComponent
|
206
|
+
<% end %>
|
207
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
208
|
+
SelectComponent
|
209
|
+
<% end %>
|
210
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
211
|
+
CheckboxComponent
|
212
|
+
<% end %>
|
213
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
214
|
+
SwitchComponent
|
215
|
+
<% end %>
|
216
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
217
|
+
LabelComponent
|
218
|
+
<% end %>
|
219
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
220
|
+
ButtonComponent
|
221
|
+
<% end %>
|
222
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
223
|
+
BadgeComponent
|
224
|
+
<% end %>
|
225
|
+
<%= render M9sh::BadgeComponent.new(variant: :secondary) do %>
|
226
|
+
SeparatorComponent
|
227
|
+
<% end %>
|
228
|
+
</div>
|
229
|
+
<% end %>
|
230
|
+
<% end %>
|
231
|
+
</div>
|