rivet_cms 0.1.0.pre
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/builds/rivet_cms.css +2 -0
- data/app/assets/builds/rivet_cms.js +9536 -0
- data/app/assets/builds/rivet_cms.js.map +7 -0
- data/app/assets/stylesheets/rivet_cms/application.tailwind.css +25 -0
- data/app/assets/stylesheets/rivet_cms/brand_colors.css +168 -0
- data/app/controllers/rivet_cms/api/docs_controller.rb +38 -0
- data/app/controllers/rivet_cms/application_controller.rb +5 -0
- data/app/controllers/rivet_cms/components_controller.rb +7 -0
- data/app/controllers/rivet_cms/content_types_controller.rb +61 -0
- data/app/controllers/rivet_cms/dashboard_controller.rb +10 -0
- data/app/controllers/rivet_cms/fields_controller.rb +109 -0
- data/app/helpers/rivet_cms/application_helper.rb +7 -0
- data/app/helpers/rivet_cms/brand_color_helper.rb +71 -0
- data/app/helpers/rivet_cms/flash_helper.rb +37 -0
- data/app/helpers/rivet_cms/sign_out_helper.rb +11 -0
- data/app/javascript/controllers/content_type_form_controller.js +53 -0
- data/app/javascript/controllers/field_layout_controller.js +709 -0
- data/app/javascript/rivet_cms.js +29 -0
- data/app/jobs/rivet_cms/application_job.rb +4 -0
- data/app/mailers/rivet_cms/application_mailer.rb +6 -0
- data/app/models/rivet_cms/application_record.rb +5 -0
- data/app/models/rivet_cms/component.rb +4 -0
- data/app/models/rivet_cms/content.rb +4 -0
- data/app/models/rivet_cms/content_type.rb +40 -0
- data/app/models/rivet_cms/content_value.rb +4 -0
- data/app/models/rivet_cms/field.rb +82 -0
- data/app/models/rivet_cms/field_values/base.rb +11 -0
- data/app/models/rivet_cms/field_values/boolean.rb +4 -0
- data/app/models/rivet_cms/field_values/integer.rb +4 -0
- data/app/models/rivet_cms/field_values/string.rb +4 -0
- data/app/models/rivet_cms/field_values/text.rb +4 -0
- data/app/services/rivet_cms/open_api_generator.rb +245 -0
- data/app/views/layouts/rivet_cms/application.html.erb +49 -0
- data/app/views/rivet_cms/api/docs/show.html.erb +47 -0
- data/app/views/rivet_cms/content_types/_form.html.erb +98 -0
- data/app/views/rivet_cms/content_types/edit.html.erb +27 -0
- data/app/views/rivet_cms/content_types/index.html.erb +151 -0
- data/app/views/rivet_cms/content_types/new.html.erb +19 -0
- data/app/views/rivet_cms/content_types/show.html.erb +147 -0
- data/app/views/rivet_cms/dashboard/index.html.erb +263 -0
- data/app/views/rivet_cms/fields/_form.html.erb +111 -0
- data/app/views/rivet_cms/fields/edit.html.erb +25 -0
- data/app/views/rivet_cms/fields/index.html.erb +126 -0
- data/app/views/rivet_cms/fields/new.html.erb +25 -0
- data/app/views/rivet_cms/shared/_navigation.html.erb +153 -0
- data/config/i18n-tasks.yml +178 -0
- data/config/locales/en.yml +14 -0
- data/config/routes.rb +56 -0
- data/db/migrate/20250317194359_create_core_tables.rb +90 -0
- data/lib/rivet_cms/engine.rb +55 -0
- data/lib/rivet_cms/version.rb +3 -0
- data/lib/rivet_cms.rb +44 -0
- data/lib/tasks/rivet_cms_tasks.rake +4 -0
- metadata +231 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
<%= form_with(model: [content_type, field],
|
2
|
+
id: "field_form",
|
3
|
+
class: "space-y-8",
|
4
|
+
data: {
|
5
|
+
controller: "field-form"
|
6
|
+
}) do |form| %>
|
7
|
+
<% if field.errors.any? %>
|
8
|
+
<div class="rounded-md bg-red-50 p-4 mb-6 border border-red-100">
|
9
|
+
<div class="flex">
|
10
|
+
<div class="flex-shrink-0">
|
11
|
+
<svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor">
|
12
|
+
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
|
13
|
+
</svg>
|
14
|
+
</div>
|
15
|
+
<div class="ml-3">
|
16
|
+
<h3 class="text-sm font-medium text-red-800">There were <%= pluralize(field.errors.count, "error") %> with this field:</h3>
|
17
|
+
<div class="mt-2 text-sm text-red-700">
|
18
|
+
<ul class="list-disc pl-5 space-y-1">
|
19
|
+
<% field.errors.full_messages.each do |message| %>
|
20
|
+
<li><%= message %></li>
|
21
|
+
<% end %>
|
22
|
+
</ul>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
<% end %>
|
28
|
+
|
29
|
+
<div class="bg-white shadow-md rounded-lg overflow-hidden border border-gray-100">
|
30
|
+
<div class="px-6 py-5 border-b border-gray-200 bg-gray-50">
|
31
|
+
<h3 class="text-lg font-medium leading-6 text-gray-900"><%= field.new_record? ? "Add Field" : "Edit Field" %></h3>
|
32
|
+
<p class="mt-1 text-sm text-gray-500">
|
33
|
+
<%= field.new_record? ? "Configure the properties of your new field." : "Update the properties of this field." %>
|
34
|
+
</p>
|
35
|
+
</div>
|
36
|
+
|
37
|
+
<div class="px-6 py-6 space-y-8">
|
38
|
+
<div>
|
39
|
+
<%= form.label :name, class: "block text-sm font-medium text-gray-700 mb-1" %>
|
40
|
+
<div class="relative mt-1 group">
|
41
|
+
<%= form.text_field :name,
|
42
|
+
class: "block w-full pl-10 px-4 py-3 rounded-md border-gray-300 shadow-sm focus:ring-brand-500 focus:border-brand-500 sm:text-sm transition-all duration-200 group-hover:border-brand-300",
|
43
|
+
placeholder: "e.g. Title, Description, Image",
|
44
|
+
data: { field_form_target: "name" } %>
|
45
|
+
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
46
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400 group-hover:text-brand-500 transition-colors duration-200" viewBox="0 0 20 20" fill="currentColor">
|
47
|
+
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z" />
|
48
|
+
<path fill-rule="evenodd" d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" clip-rule="evenodd" />
|
49
|
+
</svg>
|
50
|
+
</div>
|
51
|
+
</div>
|
52
|
+
<p class="mt-2 text-sm text-gray-500">The display name of the field.</p>
|
53
|
+
</div>
|
54
|
+
|
55
|
+
<div>
|
56
|
+
<%= form.label :field_type, class: "block text-sm font-medium text-gray-700 mb-1" %>
|
57
|
+
<div class="relative mt-1 group">
|
58
|
+
<%= form.select :field_type,
|
59
|
+
RivetCms::Field.field_types_for_select,
|
60
|
+
{},
|
61
|
+
class: "block w-full pl-10 px-4 py-3 rounded-md border-gray-300 shadow-sm focus:ring-brand-500 focus:border-brand-500 sm:text-sm transition-all duration-200 group-hover:border-brand-300" %>
|
62
|
+
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
63
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400 group-hover:text-brand-500 transition-colors duration-200" viewBox="0 0 20 20" fill="currentColor">
|
64
|
+
<path fill-rule="evenodd" d="M3 5a2 2 0 012-2h10a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V5zm11 1H6v8l4-2 4 2V6z" clip-rule="evenodd" />
|
65
|
+
</svg>
|
66
|
+
</div>
|
67
|
+
</div>
|
68
|
+
<p class="mt-2 text-sm text-gray-500">The type of data this field will store.</p>
|
69
|
+
</div>
|
70
|
+
|
71
|
+
<div>
|
72
|
+
<%= form.label :description, class: "block text-sm font-medium text-gray-700 mb-1" %>
|
73
|
+
<div class="relative mt-1 group">
|
74
|
+
<%= form.text_area :description,
|
75
|
+
rows: 3,
|
76
|
+
class: "block w-full pl-10 px-4 py-3 rounded-md border-gray-300 shadow-sm focus:ring-brand-500 focus:border-brand-500 sm:text-sm transition-all duration-200 group-hover:border-brand-300",
|
77
|
+
placeholder: "Optional description of this field" %>
|
78
|
+
<div class="absolute top-3 left-0 pl-3 flex items-start pointer-events-none">
|
79
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400 group-hover:text-brand-500 transition-colors duration-200" viewBox="0 0 20 20" fill="currentColor">
|
80
|
+
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />
|
81
|
+
</svg>
|
82
|
+
</div>
|
83
|
+
</div>
|
84
|
+
<p class="mt-2 text-sm text-gray-500">A helpful description for content editors.</p>
|
85
|
+
</div>
|
86
|
+
|
87
|
+
<div class="pt-2">
|
88
|
+
<div class="relative flex items-start">
|
89
|
+
<div class="flex items-center h-5">
|
90
|
+
<%= form.check_box :required,
|
91
|
+
class: "h-5 w-5 rounded border-gray-300 text-brand-600 focus:ring-brand-500 transition-all duration-200",
|
92
|
+
data: { field_form_target: "required" } %>
|
93
|
+
</div>
|
94
|
+
<div class="ml-3 text-sm">
|
95
|
+
<%= form.label :required, "Required Field", class: "font-medium text-gray-700" %>
|
96
|
+
<p class="text-gray-500">Make this field mandatory when creating or editing content.</p>
|
97
|
+
</div>
|
98
|
+
</div>
|
99
|
+
</div>
|
100
|
+
</div>
|
101
|
+
</div>
|
102
|
+
|
103
|
+
<div class="flex justify-end pt-4 space-x-3">
|
104
|
+
<%= link_to content_type_fields_path(content_type),
|
105
|
+
class: "cursor-pointer rounded-md border border-gray-300 bg-white py-2 px-4 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 transition-all duration-200" do %>
|
106
|
+
Cancel
|
107
|
+
<% end %>
|
108
|
+
<%= form.submit field.new_record? ? "Create Field" : "Update Field",
|
109
|
+
class: "cursor-pointer inline-flex justify-center rounded-md border border-transparent bg-brand-600 py-2 px-4 text-sm font-medium text-white shadow-sm hover:bg-brand-700 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 transition-all duration-200" %>
|
110
|
+
</div>
|
111
|
+
<% end %>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 space-y-8">
|
2
|
+
<div class="sm:flex sm:items-center">
|
3
|
+
<div class="sm:flex-auto">
|
4
|
+
<div class="flex items-center">
|
5
|
+
<h1 class="text-2xl font-bold text-gray-900">Edit Field: <%= @field.name %></h1>
|
6
|
+
<span class="ml-3 inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium <%= @content_type.is_single ? 'bg-amber-100 text-amber-800 border border-amber-200' : 'bg-teal-100 text-teal-800 border border-teal-200' %>">
|
7
|
+
<%= @content_type.is_single ? "Single Type" : "Collection" %>
|
8
|
+
</span>
|
9
|
+
</div>
|
10
|
+
<p class="mt-2 text-sm text-gray-700">
|
11
|
+
Modify the properties of this field.
|
12
|
+
</p>
|
13
|
+
</div>
|
14
|
+
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
|
15
|
+
<%= link_to content_type_fields_path(@content_type), class: "inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2" do %>
|
16
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2 -ml-1 text-gray-500" viewBox="0 0 20 20" fill="currentColor">
|
17
|
+
<path fill-rule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clip-rule="evenodd" />
|
18
|
+
</svg>
|
19
|
+
Back
|
20
|
+
<% end %>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<%= render 'form', content_type: @content_type, field: @field %>
|
25
|
+
</div>
|
@@ -0,0 +1,126 @@
|
|
1
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-6">
|
2
|
+
<div class="sm:flex sm:items-center">
|
3
|
+
<div class="sm:flex-auto">
|
4
|
+
<div class="flex items-center">
|
5
|
+
<h1 class="text-2xl font-bold text-gray-900">Structure: <%= @content_type.name %></h1>
|
6
|
+
<span class="ml-3 inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium <%= @content_type.is_single ? 'bg-amber-100 text-amber-800 border border-amber-200' : 'bg-teal-100 text-teal-800 border border-teal-200' %>">
|
7
|
+
<%= @content_type.is_single ? "Single Type" : "Collection" %>
|
8
|
+
</span>
|
9
|
+
</div>
|
10
|
+
<p class="mt-2 text-sm text-gray-700">
|
11
|
+
Define the structure of your content type by adding and arranging fields.
|
12
|
+
</p>
|
13
|
+
</div>
|
14
|
+
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
|
15
|
+
<%= link_to new_content_type_field_path(@content_type), class: "inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-brand-600 hover:bg-brand-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-brand-500 transition-all duration-200" do %>
|
16
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="-ml-1 mr-2 h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
17
|
+
<path fill-rule="evenodd" d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z" clip-rule="evenodd" />
|
18
|
+
</svg>
|
19
|
+
Add Field
|
20
|
+
<% end %>
|
21
|
+
<%= link_to content_type_path(@content_type), class: "ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray- focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2" do %>
|
22
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2 -ml-1 text-gray-500" viewBox="0 0 20 20" fill="currentColor">
|
23
|
+
<path fill-rule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clip-rule="evenodd" />
|
24
|
+
</svg>
|
25
|
+
Back
|
26
|
+
<% end %>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<div class="mt-6 bg-white shadow-md rounded-lg overflow-hidden border border-gray-100">
|
31
|
+
<div class="px-4 py-4 border-b border-gray-200 bg-gray-50">
|
32
|
+
<h3 class="text-lg font-medium leading-6 text-gray-900">Fields</h3>
|
33
|
+
<p class="mt-1 text-sm text-gray-500">
|
34
|
+
Drag and drop to reorder fields. Click on a field to edit its properties.
|
35
|
+
<span class="block mt-1">To stack half-width fields, drag the second field slightly lower than the first. To place them side by side, make sure they're at the same vertical position.</span>
|
36
|
+
</p>
|
37
|
+
</div>
|
38
|
+
|
39
|
+
<% if @fields.any? %>
|
40
|
+
<div id="sortable-fields"
|
41
|
+
data-controller="field-layout"
|
42
|
+
data-field-layout-target="fieldContainer"
|
43
|
+
data-field-layout-content-type-id-value="<%= @content_type.to_param %>"
|
44
|
+
data-update-positions-path="<%= update_positions_content_type_fields_path(@content_type) %>"
|
45
|
+
data-content-type-id="<%= @content_type.to_param %>"
|
46
|
+
class="p-4 grid gap-3">
|
47
|
+
<% @fields.order(:position).each do |field| %>
|
48
|
+
<div class="field-item"
|
49
|
+
data-field-layout-target="field"
|
50
|
+
data-field-id="<%= field.to_param %>"
|
51
|
+
data-width="<%= field.width || 'full' %>"
|
52
|
+
data-row-group="<%= field.row_group || field.position %>"
|
53
|
+
data-position="<%= field.position %>"
|
54
|
+
data-update-width-path="<%= update_width_content_type_field_path(@content_type, field) %>">
|
55
|
+
<div class="flex items-center justify-between h-12 rounded-lg">
|
56
|
+
<div class="flex items-center flex-1">
|
57
|
+
<div class="cursor-move mr-3 text-gray-400 hover:text-gray-600">
|
58
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
59
|
+
<path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
|
60
|
+
</svg>
|
61
|
+
</div>
|
62
|
+
<div class="min-w-0 flex-1">
|
63
|
+
<h4 class="text-sm font-medium text-gray-900 truncate"><%= field.name %></h4>
|
64
|
+
<div class="flex items-center">
|
65
|
+
<span class="inline-flex items-center rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-800">
|
66
|
+
<%= field.field_type_name %>
|
67
|
+
</span>
|
68
|
+
<% if field.required %>
|
69
|
+
<span class="ml-2 inline-flex items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-800">
|
70
|
+
Required
|
71
|
+
</span>
|
72
|
+
<% end %>
|
73
|
+
</div>
|
74
|
+
</div>
|
75
|
+
</div>
|
76
|
+
<div class="flex items-center space-x-2">
|
77
|
+
<button type="button"
|
78
|
+
class="toggle-width-button text-gray-500 hover:text-gray-700 transition-colors duration-150 p-1 hover:bg-gray-200 rounded-full"
|
79
|
+
data-action="click->field-layout#toggleWidth">
|
80
|
+
<span class="sr-only">Toggle width</span>
|
81
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-5 w-5">
|
82
|
+
<% if field.width == 'full' %>
|
83
|
+
<path d="m15 15 6 6m-6-6v4.8m0-4.8h4.8"/><path d="M9 19.8V15m0 0H4.2M9 15l-6 6"/><path d="M15 9l6-6m-6 6V4.2m0 4.8h4.8"/><path d="M9 4.2V9m0 0H4.2M9 9 3 3"/>
|
84
|
+
<% else %>
|
85
|
+
<path d="m21 21-6-6m6 6v-4.8m0 4.8h-4.8"/><path d="M3 16.2V21m0 0h4.8M3 21l6-6"/><path d="M21 7.8V3m0 0h-4.8M21 3l-6 6"/><path d="M3 7.8V3m0 0h4.8M3 3l6 6"/>
|
86
|
+
<% end %>
|
87
|
+
</svg>
|
88
|
+
</button>
|
89
|
+
<%= link_to edit_content_type_field_path(@content_type, field), class: "text-amber-500 hover:text-amber-700 transition-colors duration-150 p-1 hover:bg-amber-100 rounded-full" do %>
|
90
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
91
|
+
<path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" />
|
92
|
+
</svg>
|
93
|
+
<% end %>
|
94
|
+
<%= button_to content_type_field_path(@content_type, field),
|
95
|
+
method: :delete,
|
96
|
+
class: "text-red-500 hover:text-red-700 transition-colors duration-150 p-1 hover:bg-red-100 rounded-full",
|
97
|
+
form_class: "flex items-center",
|
98
|
+
data: { confirm: "Are you sure you want to delete this field? This will also delete all associated data." } do %>
|
99
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
100
|
+
<path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd" />
|
101
|
+
</svg>
|
102
|
+
<% end %>
|
103
|
+
</div>
|
104
|
+
</div>
|
105
|
+
</div>
|
106
|
+
<% end %>
|
107
|
+
</div>
|
108
|
+
<% else %>
|
109
|
+
<div class="px-4 py-8 text-center">
|
110
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="mx-auto h-12 w-12 text-gray-300" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
111
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
|
112
|
+
</svg>
|
113
|
+
<h3 class="mt-2 text-sm font-medium text-gray-900">No fields</h3>
|
114
|
+
<p class="mt-1 text-sm text-gray-500">Get started by creating a new field.</p>
|
115
|
+
<div class="mt-6">
|
116
|
+
<%= link_to new_content_type_field_path(@content_type), class: "inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-brand-600 hover:bg-brand-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-brand-500 transition-all duration-200" do %>
|
117
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="-ml-1 mr-2 h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
118
|
+
<path fill-rule="evenodd" d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z" clip-rule="evenodd" />
|
119
|
+
</svg>
|
120
|
+
Add Field
|
121
|
+
<% end %>
|
122
|
+
</div>
|
123
|
+
</div>
|
124
|
+
<% end %>
|
125
|
+
</div>
|
126
|
+
</div>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 space-y-8">
|
2
|
+
<div class="sm:flex sm:items-center">
|
3
|
+
<div class="sm:flex-auto">
|
4
|
+
<div class="flex items-center">
|
5
|
+
<h1 class="text-2xl font-bold text-gray-900">Add Field: <%= @content_type.name %></h1>
|
6
|
+
<span class="ml-3 inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium <%= @content_type.is_single ? 'bg-amber-100 text-amber-800 border border-amber-200' : 'bg-teal-100 text-teal-800 border border-teal-200' %>">
|
7
|
+
<%= @content_type.is_single ? "Single Type" : "Collection" %>
|
8
|
+
</span>
|
9
|
+
</div>
|
10
|
+
<p class="mt-2 text-sm text-gray-700">
|
11
|
+
Add a new field to your content type structure.
|
12
|
+
</p>
|
13
|
+
</div>
|
14
|
+
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
|
15
|
+
<%= link_to content_type_fields_path(@content_type), class: "inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2" do %>
|
16
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2 -ml-1 text-gray-500" viewBox="0 0 20 20" fill="currentColor">
|
17
|
+
<path fill-rule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clip-rule="evenodd" />
|
18
|
+
</svg>
|
19
|
+
Back
|
20
|
+
<% end %>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<%= render 'form', content_type: @content_type, field: @field %>
|
25
|
+
</div>
|
@@ -0,0 +1,153 @@
|
|
1
|
+
<nav class="bg-white shadow-sm border-b border-gray-200 py-2">
|
2
|
+
<div class="w-full px-4 sm:px-6 lg:px-8">
|
3
|
+
<div class="flex h-16 justify-between items-center">
|
4
|
+
<div class="flex-shrink-0 flex items-center">
|
5
|
+
<%= link_to dashboard_path do %>
|
6
|
+
<h1 class="text-xl font-bold text-gray-900 flex items-center">
|
7
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-boxes mr-2 text-brand-600">
|
8
|
+
<path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z"/>
|
9
|
+
<path d="m7 16.5-4.74-2.85"/>
|
10
|
+
<path d="m7 16.5 5-3"/>
|
11
|
+
<path d="M7 16.5v5.17"/>
|
12
|
+
<path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z"/>
|
13
|
+
<path d="m17 16.5-5-3"/>
|
14
|
+
<path d="m17 16.5 4.74-2.85"/>
|
15
|
+
<path d="M17 16.5v5.17"/>
|
16
|
+
<path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z"/>
|
17
|
+
<path d="M12 8 7.26 5.15"/>
|
18
|
+
<path d="m12 8 4.74-2.85"/>
|
19
|
+
<path d="M12 13.5V8"/>
|
20
|
+
</svg>
|
21
|
+
<span class="font-passion-one text-3xl">RivetCMS</span>
|
22
|
+
</h1>
|
23
|
+
<% end %>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<div class="hidden lg:flex lg:justify-center lg:flex-1 lg:items-center">
|
27
|
+
<div class="flex space-x-3 xl:space-x-4 2xl:space-x-6">
|
28
|
+
<%= link_to dashboard_path, class: current_page?(dashboard_path) ? "inline-flex items-center border-b-2 border-brand-600 px-1 pt-1 text-sm font-medium text-brand-700" : "inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-600 hover:border-gray-300 hover:text-gray-800" do %>
|
29
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-home mr-1"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
30
|
+
<span><%= t(".dashboard") %></span>
|
31
|
+
<% end %>
|
32
|
+
<%= link_to "#", class: controller_name == 'contents' ? "inline-flex items-center border-b-2 border-brand-600 px-1 pt-1 text-sm font-medium text-brand-700" : "inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-600 hover:border-gray-300 hover:text-gray-800" do %>
|
33
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text mr-1"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/><line x1="16" x2="8" y1="13" y2="13"/><line x1="16" x2="8" y1="17" y2="17"/><line x1="10" x2="8" y1="9" y2="9"/></svg>
|
34
|
+
<span><%= t(".content") %></span>
|
35
|
+
<% end %>
|
36
|
+
<%= link_to content_types_path, class: controller_name == 'content_types' ? "inline-flex items-center border-b-2 border-brand-600 px-1 pt-1 text-sm font-medium text-brand-700" : "inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-600 hover:border-gray-300 hover:text-gray-800" do %>
|
37
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layers mr-1"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>
|
38
|
+
<span class="xl:inline hidden"><%= t(".content_types") %></span>
|
39
|
+
<span class="xl:hidden"><%= t(".content_types_short") %></span>
|
40
|
+
<% end %>
|
41
|
+
<%= link_to components_path, class: controller_name == 'components' ? "inline-flex items-center border-b-2 border-brand-600 px-1 pt-1 text-sm font-medium text-brand-700" : "inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-600 hover:border-gray-300 hover:text-gray-800" do %>
|
42
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layout-grid mr-1"><rect width="7" height="7" x="3" y="3" rx="1"/><rect width="7" height="7" x="14" y="3" rx="1"/><rect width="7" height="7" x="14" y="14" rx="1"/><rect width="7" height="7" x="3" y="14" rx="1"/></svg>
|
43
|
+
<span class="xl:inline hidden"><%= t(".components") %></span>
|
44
|
+
<span class="xl:hidden"><%= t(".components_short") %></span>
|
45
|
+
<% end %>
|
46
|
+
<%= link_to "#", class: "inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-600 hover:border-gray-300 hover:text-gray-800" do %>
|
47
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-image mr-1"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></svg>
|
48
|
+
<span><%= t(".media") %></span>
|
49
|
+
<% end %>
|
50
|
+
<%= link_to "#", class: controller_name == 'users' ? "inline-flex items-center border-b-2 border-brand-600 px-1 pt-1 text-sm font-medium text-brand-700" : "inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-600 hover:border-gray-300 hover:text-gray-800" do %>
|
51
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-users mr-1"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
52
|
+
<span><%= t(".users") %></span>
|
53
|
+
<% end %>
|
54
|
+
<%= link_to api_docs_path, class: "inline-flex items-center border-b-2 border-transparent px-1 pt-1 text-sm font-medium text-gray-600 hover:border-gray-300 hover:text-gray-800", target: "_blank" do %>
|
55
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-book-open mr-1"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
|
56
|
+
<span class="xl:inline hidden"><%= t(".api_docs") %></span>
|
57
|
+
<% end %>
|
58
|
+
</div>
|
59
|
+
</div>
|
60
|
+
|
61
|
+
<!-- Right side icons -->
|
62
|
+
<div class="flex items-center space-x-4">
|
63
|
+
<!-- Pro version link -->
|
64
|
+
<a href="#" class="inline-flex items-center rounded-md bg-gray-800 px-3 py-1.5 text-sm font-medium text-white shadow-sm hover:bg-gray-700 transition-colors">
|
65
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-sparkles mr-1"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/><path d="M5 3v4"/><path d="M19 17v4"/><path d="M3 5h4"/><path d="M17 19h4"/></svg>
|
66
|
+
<span class="md:hidden">Upgrade</span><span class="hidden md:inline">Upgrade to Pro</span>
|
67
|
+
</a>
|
68
|
+
|
69
|
+
<!-- Help button -->
|
70
|
+
<button type="button" class="rounded-full bg-brand-50 p-1 text-brand-600 hover:bg-brand-100 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2">
|
71
|
+
<span class="sr-only">View help</span>
|
72
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-help"><path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" x2="12.01" y1="17" y2="17"/></svg>
|
73
|
+
</button>
|
74
|
+
<div class="relative">
|
75
|
+
<button type="button" class="flex rounded-full bg-brand-50 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2" id="user-menu-button" aria-expanded="false" aria-haspopup="true">
|
76
|
+
<span class="sr-only">Open user menu</span>
|
77
|
+
<span class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-white border border-brand-100">
|
78
|
+
<span class="text-sm font-medium leading-none text-brand-700">
|
79
|
+
|
80
|
+
</span>
|
81
|
+
</span>
|
82
|
+
</button>
|
83
|
+
</div>
|
84
|
+
|
85
|
+
<!-- Mobile menu button -->
|
86
|
+
<div class="lg:hidden">
|
87
|
+
<button type="button" class="inline-flex items-center justify-center rounded-md p-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-brand-500" aria-controls="mobile-menu" aria-expanded="false">
|
88
|
+
<span class="sr-only">Open main menu</span>
|
89
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-menu block h-6 w-6">
|
90
|
+
<line x1="4" x2="20" y1="12" y2="12" />
|
91
|
+
<line x1="4" x2="20" y1="6" y2="6" />
|
92
|
+
<line x1="4" x2="20" y1="18" y2="18" />
|
93
|
+
</svg>
|
94
|
+
</button>
|
95
|
+
</div>
|
96
|
+
</div>
|
97
|
+
</div>
|
98
|
+
</div>
|
99
|
+
|
100
|
+
<!-- Mobile menu, show/hide based on menu state. -->
|
101
|
+
<div class="hidden lg:hidden" id="mobile-menu">
|
102
|
+
<div class="space-y-1 pb-3 pt-2">
|
103
|
+
<%= link_to dashboard_path, class: current_page?(dashboard_path) ? "block border-l-4 border-brand-600 bg-brand-50 py-2 pl-3 pr-4 text-base font-medium text-brand-700" : "block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800" do %>
|
104
|
+
<div class="flex items-center">
|
105
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-home mr-2"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
106
|
+
Dashboard
|
107
|
+
</div>
|
108
|
+
<% end %>
|
109
|
+
<%= link_to "#", class: controller_name == 'contents' ? "block border-l-4 border-brand-600 bg-brand-50 py-2 pl-3 pr-4 text-base font-medium text-brand-700" : "block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800" do %>
|
110
|
+
<div class="flex items-center">
|
111
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text mr-2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/><line x1="16" x2="8" y1="13" y2="13"/><line x1="16" x2="8" y1="17" y2="17"/><line x1="10" x2="8" y1="9" y2="9"/></svg>
|
112
|
+
Content
|
113
|
+
</div>
|
114
|
+
<% end %>
|
115
|
+
<%= link_to content_types_path, class: controller_name == 'content_types' ? "block border-l-4 border-brand-600 bg-brand-50 py-2 pl-3 pr-4 text-base font-medium text-brand-700" : "block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800" do %>
|
116
|
+
<div class="flex items-center">
|
117
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layers mr-2"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>
|
118
|
+
Content Types
|
119
|
+
</div>
|
120
|
+
<% end %>
|
121
|
+
<%= link_to components_path, class: controller_name == 'components' ? "block border-l-4 border-brand-600 bg-brand-50 py-2 pl-3 pr-4 text-base font-medium text-brand-700" : "block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800" do %>
|
122
|
+
<div class="flex items-center">
|
123
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layout-grid mr-2"><rect width="7" height="7" x="3" y="3" rx="1"/><rect width="7" height="7" x="14" y="3" rx="1"/><rect width="7" height="7" x="14" y="14" rx="1"/><rect width="7" height="7" x="3" y="14" rx="1"/></svg>
|
124
|
+
Components
|
125
|
+
</div>
|
126
|
+
<% end %>
|
127
|
+
<%= link_to "#", class: "block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800" do %>
|
128
|
+
<div class="flex items-center">
|
129
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-image mr-2"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></svg>
|
130
|
+
Media Library
|
131
|
+
</div>
|
132
|
+
<% end %>
|
133
|
+
<%= link_to "#", class: controller_name == 'users' ? "block border-l-4 border-brand-600 bg-brand-50 py-2 pl-3 pr-4 text-base font-medium text-brand-700" : "block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800" do %>
|
134
|
+
<div class="flex items-center">
|
135
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-users mr-2"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
136
|
+
Users
|
137
|
+
</div>
|
138
|
+
<% end %>
|
139
|
+
<%= link_to api_docs_path, class: "block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800", target: "_blank" do %>
|
140
|
+
<div class="flex items-center">
|
141
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-book-open mr-2"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
|
142
|
+
API Docs
|
143
|
+
</div>
|
144
|
+
<% end %>
|
145
|
+
<div class="mt-4 border-t border-gray-200 pt-4 px-3">
|
146
|
+
<a href="#" class="flex items-center justify-center rounded-md bg-gray-800 !bg-gray-800 px-3 py-2 text-base font-medium text-white shadow-sm hover:bg-gray-700 !hover:bg-gray-700 transition-colors">
|
147
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-sparkles mr-2"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/><path d="M5 3v4"/><path d="M19 17v4"/><path d="M3 5h4"/><path d="M17 19h4"/></svg>
|
148
|
+
Upgrade to Pro
|
149
|
+
</a>
|
150
|
+
</div>
|
151
|
+
</div>
|
152
|
+
</div>
|
153
|
+
</nav>
|