rivet_cms 0.1.2.pre → 0.3.0
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/CHANGELOG.md +53 -0
- data/COPYING +674 -0
- data/COPYING.LESSER +165 -0
- data/README.md +173 -10
- data/app/assets/builds/rivet_cms.css +2 -2
- data/app/assets/builds/rivet_cms.js +395 -9505
- data/app/assets/stylesheets/rivet_cms/application.tailwind.css +145 -22
- data/app/controllers/concerns/rivet_cms/inertia_props.rb +239 -0
- data/app/controllers/rivet_cms/api_docs_controller.rb +47 -0
- data/app/controllers/rivet_cms/api_tokens_controller.rb +43 -0
- data/app/controllers/rivet_cms/application_controller.rb +220 -2
- data/app/controllers/rivet_cms/auth_controller.rb +28 -0
- data/app/controllers/rivet_cms/components_controller.rb +93 -2
- data/app/controllers/rivet_cms/content_controller.rb +105 -0
- data/app/controllers/rivet_cms/content_manager_controller.rb +32 -0
- data/app/controllers/rivet_cms/content_types_controller.rb +118 -26
- data/app/controllers/rivet_cms/dashboard_controller.rb +55 -5
- data/app/controllers/rivet_cms/documents_controller.rb +204 -0
- data/app/controllers/rivet_cms/fields_controller.rb +77 -74
- data/app/controllers/rivet_cms/invitations_controller.rb +36 -0
- data/app/controllers/rivet_cms/media_assets_controller.rb +76 -0
- data/app/controllers/rivet_cms/sessions_controller.rb +122 -0
- data/app/controllers/rivet_cms/setup_controller.rb +60 -0
- data/app/controllers/rivet_cms/trash_controller.rb +68 -0
- data/app/controllers/rivet_cms/users_controller.rb +117 -0
- data/app/helpers/rivet_cms/application_helper.rb +13 -3
- data/app/helpers/rivet_cms/components_helper.rb +4 -0
- data/app/helpers/rivet_cms/content_types_helper.rb +4 -0
- data/app/helpers/rivet_cms/dashboard_helper.rb +4 -0
- data/app/jobs/rivet_cms/webhook_delivery_job.rb +35 -0
- data/app/models/concerns/rivet_cms/has_fields.rb +31 -0
- data/app/models/concerns/rivet_cms/organization_scoped.rb +17 -0
- data/app/models/concerns/rivet_cms/revision_owned.rb +36 -0
- data/app/models/concerns/rivet_cms/sluggable.rb +38 -0
- data/app/models/concerns/rivet_cms/soft_deletable.rb +42 -0
- data/app/models/concerns/rivet_cms/typed_value.rb +51 -0
- data/app/models/rivet_cms/api_token.rb +64 -0
- data/app/models/rivet_cms/category.rb +20 -0
- data/app/models/rivet_cms/component.rb +10 -0
- data/app/models/rivet_cms/component_instance.rb +27 -0
- data/app/models/rivet_cms/content_type.rb +36 -23
- data/app/models/rivet_cms/content_value.rb +19 -0
- data/app/models/rivet_cms/current.rb +6 -0
- data/app/models/rivet_cms/document.rb +71 -0
- data/app/models/rivet_cms/document_revision.rb +128 -0
- data/app/models/rivet_cms/entry.rb +73 -0
- data/app/models/rivet_cms/entry_collection.rb +41 -0
- data/app/models/rivet_cms/field.rb +203 -61
- data/app/models/rivet_cms/media_asset.rb +109 -0
- data/app/models/rivet_cms/organization.rb +46 -0
- data/app/models/rivet_cms/relation.rb +23 -0
- data/app/models/rivet_cms/user.rb +61 -0
- data/app/serializers/rivet_cms/revision_preloader.rb +146 -0
- data/app/serializers/rivet_cms/revision_serializer.rb +123 -0
- data/app/services/rivet_cms/content_query.rb +158 -0
- data/app/services/rivet_cms/content_validator.rb +150 -0
- data/app/services/rivet_cms/draft_writer.rb +74 -0
- data/app/services/rivet_cms/open_api_generator.rb +173 -221
- data/app/services/rivet_cms/revision_pruner.rb +64 -0
- data/app/services/rivet_cms/webhooks.rb +61 -0
- data/app/views/layouts/rivet_cms/application.html.erb +35 -42
- data/config/routes.rb +68 -45
- data/db/migrate/20251119193607_create_rivet_cms_organizations.rb +17 -0
- data/db/migrate/20251120050818_create_rivet_cms_content_types.rb +14 -0
- data/db/migrate/20251121020625_create_rivet_cms_components.rb +14 -0
- data/db/migrate/20251121040115_create_rivet_cms_categories.rb +14 -0
- data/db/migrate/20260119185946_create_content_system_tables.rb +95 -0
- data/db/migrate/20260722000001_create_rivet_cms_media_assets.rb +15 -0
- data/db/migrate/20260722000002_create_rivet_cms_api_tokens.rb +16 -0
- data/db/migrate/20260806000001_add_title_and_alt_to_rivet_cms_media_assets.rb +7 -0
- data/db/migrate/20260806000002_add_deleted_at_to_rivet_cms_content_types.rb +6 -0
- data/db/migrate/20260807000001_add_deleted_at_to_rivet_cms_documents.rb +6 -0
- data/db/migrate/20260808000001_create_rivet_cms_users.rb +15 -0
- data/db/seeds/README.md +70 -0
- data/db/seeds/templates/blog.rb +39 -0
- data/db/seeds/templates/events.rb +12 -0
- data/db/seeds/templates/faq.rb +9 -0
- data/db/seeds/templates/pages.rb +35 -0
- data/db/seeds/templates/site_settings.rb +22 -0
- data/db/seeds/templates/team.rb +11 -0
- data/db/seeds/templates/testimonials.rb +11 -0
- data/lib/generators/rivet_cms/install/install_generator.rb +13 -0
- data/lib/generators/rivet_cms/install/templates/initializer.rb +77 -0
- data/lib/rivet_cms/access_check.rb +12 -0
- data/lib/rivet_cms/audit.rb +43 -0
- data/lib/rivet_cms/engine.rb +28 -22
- data/lib/rivet_cms/hooks.rb +106 -0
- data/lib/rivet_cms/navigation.rb +111 -0
- data/lib/rivet_cms/safe_pattern.rb +40 -0
- data/lib/rivet_cms/seeds.rb +264 -0
- data/lib/rivet_cms/version.rb +1 -1
- data/lib/rivet_cms.rb +289 -32
- data/lib/tasks/rivet_cms_tasks.rake +18 -4
- metadata +138 -98
- data/MIT-LICENSE +0 -20
- data/app/assets/builds/rivet_cms.js.map +0 -7
- data/app/assets/stylesheets/rivet_cms/brand_colors.css +0 -168
- data/app/controllers/rivet_cms/api/docs_controller.rb +0 -38
- data/app/helpers/rivet_cms/brand_color_helper.rb +0 -71
- data/app/helpers/rivet_cms/flash_helper.rb +0 -37
- data/app/helpers/rivet_cms/sign_out_helper.rb +0 -11
- data/app/javascript/controllers/content_type_form_controller.js +0 -53
- data/app/javascript/controllers/field_layout_controller.js +0 -709
- data/app/javascript/rivet_cms.js +0 -29
- data/app/models/rivet_cms/content.rb +0 -4
- data/app/models/rivet_cms/field_values/base.rb +0 -11
- data/app/models/rivet_cms/field_values/boolean.rb +0 -4
- data/app/models/rivet_cms/field_values/integer.rb +0 -4
- data/app/models/rivet_cms/field_values/string.rb +0 -4
- data/app/models/rivet_cms/field_values/text.rb +0 -4
- data/app/views/rivet_cms/api/docs/show.html.erb +0 -47
- data/app/views/rivet_cms/content_types/_form.html.erb +0 -98
- data/app/views/rivet_cms/content_types/edit.html.erb +0 -27
- data/app/views/rivet_cms/content_types/index.html.erb +0 -151
- data/app/views/rivet_cms/content_types/new.html.erb +0 -19
- data/app/views/rivet_cms/content_types/show.html.erb +0 -147
- data/app/views/rivet_cms/dashboard/index.html.erb +0 -263
- data/app/views/rivet_cms/fields/_form.html.erb +0 -111
- data/app/views/rivet_cms/fields/edit.html.erb +0 -25
- data/app/views/rivet_cms/fields/index.html.erb +0 -126
- data/app/views/rivet_cms/fields/new.html.erb +0 -25
- data/app/views/rivet_cms/shared/_navigation.html.erb +0 -153
- data/config/i18n-tasks.yml +0 -178
- data/config/locales/en.yml +0 -14
- data/db/migrate/20250317194359_create_core_tables.rb +0 -90
- data/lib/rivet_cms/routes.rb +0 -49
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
This file contains overrides for brand colors.
|
|
3
|
-
It should be loaded after the main Tailwind CSS.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/* Brand color backgrounds */
|
|
7
|
-
.bg-brand-50 { background-color: var(--color-brand-50) !important; }
|
|
8
|
-
.bg-brand-100 { background-color: var(--color-brand-100) !important; }
|
|
9
|
-
.bg-brand-200 { background-color: var(--color-brand-200) !important; }
|
|
10
|
-
.bg-brand-300 { background-color: var(--color-brand-300) !important; }
|
|
11
|
-
.bg-brand-400 { background-color: var(--color-brand-400) !important; }
|
|
12
|
-
.bg-brand-500 { background-color: var(--color-brand-500) !important; }
|
|
13
|
-
.bg-brand-600 { background-color: var(--color-brand-600) !important; }
|
|
14
|
-
.bg-brand-700 { background-color: var(--color-brand-700) !important; }
|
|
15
|
-
.bg-brand-800 { background-color: var(--color-brand-800) !important; }
|
|
16
|
-
.bg-brand-900 { background-color: var(--color-brand-900) !important; }
|
|
17
|
-
.bg-brand-950 { background-color: var(--color-brand-950) !important; }
|
|
18
|
-
|
|
19
|
-
/* Brand color text */
|
|
20
|
-
.text-brand-50 { color: var(--color-brand-50) !important; }
|
|
21
|
-
.text-brand-100 { color: var(--color-brand-100) !important; }
|
|
22
|
-
.text-brand-200 { color: var(--color-brand-200) !important; }
|
|
23
|
-
.text-brand-300 { color: var(--color-brand-300) !important; }
|
|
24
|
-
.text-brand-400 { color: var(--color-brand-400) !important; }
|
|
25
|
-
.text-brand-500 { color: var(--color-brand-500) !important; }
|
|
26
|
-
.text-brand-600 { color: var(--color-brand-600) !important; }
|
|
27
|
-
.text-brand-700 { color: var(--color-brand-700) !important; }
|
|
28
|
-
.text-brand-800 { color: var(--color-brand-800) !important; }
|
|
29
|
-
.text-brand-900 { color: var(--color-brand-900) !important; }
|
|
30
|
-
.text-brand-950 { color: var(--color-brand-950) !important; }
|
|
31
|
-
|
|
32
|
-
/* Brand color borders */
|
|
33
|
-
.border-brand-50 { border-color: var(--color-brand-50) !important; }
|
|
34
|
-
.border-brand-100 { border-color: var(--color-brand-100) !important; }
|
|
35
|
-
.border-brand-200 { border-color: var(--color-brand-200) !important; }
|
|
36
|
-
.border-brand-300 { border-color: var(--color-brand-300) !important; }
|
|
37
|
-
.border-brand-400 { border-color: var(--color-brand-400) !important; }
|
|
38
|
-
.border-brand-500 { border-color: var(--color-brand-500) !important; }
|
|
39
|
-
.border-brand-600 { border-color: var(--color-brand-600) !important; }
|
|
40
|
-
.border-brand-700 { border-color: var(--color-brand-700) !important; }
|
|
41
|
-
.border-brand-800 { border-color: var(--color-brand-800) !important; }
|
|
42
|
-
.border-brand-900 { border-color: var(--color-brand-900) !important; }
|
|
43
|
-
.border-brand-950 { border-color: var(--color-brand-950) !important; }
|
|
44
|
-
|
|
45
|
-
/* Hover states */
|
|
46
|
-
.hover\:bg-brand-50:hover { background-color: var(--color-brand-50) !important; }
|
|
47
|
-
.hover\:bg-brand-100:hover { background-color: var(--color-brand-100) !important; }
|
|
48
|
-
.hover\:bg-brand-200:hover { background-color: var(--color-brand-200) !important; }
|
|
49
|
-
.hover\:bg-brand-300:hover { background-color: var(--color-brand-300) !important; }
|
|
50
|
-
.hover\:bg-brand-400:hover { background-color: var(--color-brand-400) !important; }
|
|
51
|
-
.hover\:bg-brand-500:hover { background-color: var(--color-brand-500) !important; }
|
|
52
|
-
.hover\:bg-brand-600:hover { background-color: var(--color-brand-600) !important; }
|
|
53
|
-
.hover\:bg-brand-700:hover { background-color: var(--color-brand-700) !important; }
|
|
54
|
-
.hover\:bg-brand-800:hover { background-color: var(--color-brand-800) !important; }
|
|
55
|
-
.hover\:bg-brand-900:hover { background-color: var(--color-brand-900) !important; }
|
|
56
|
-
.hover\:bg-brand-950:hover { background-color: var(--color-brand-950) !important; }
|
|
57
|
-
|
|
58
|
-
.hover\:text-brand-50:hover { color: var(--color-brand-50) !important; }
|
|
59
|
-
.hover\:text-brand-100:hover { color: var(--color-brand-100) !important; }
|
|
60
|
-
.hover\:text-brand-200:hover { color: var(--color-brand-200) !important; }
|
|
61
|
-
.hover\:text-brand-300:hover { color: var(--color-brand-300) !important; }
|
|
62
|
-
.hover\:text-brand-400:hover { color: var(--color-brand-400) !important; }
|
|
63
|
-
.hover\:text-brand-500:hover { color: var(--color-brand-500) !important; }
|
|
64
|
-
.hover\:text-brand-600:hover { color: var(--color-brand-600) !important; }
|
|
65
|
-
.hover\:text-brand-700:hover { color: var(--color-brand-700) !important; }
|
|
66
|
-
.hover\:text-brand-800:hover { color: var(--color-brand-800) !important; }
|
|
67
|
-
.hover\:text-brand-900:hover { color: var(--color-brand-900) !important; }
|
|
68
|
-
.hover\:text-brand-950:hover { color: var(--color-brand-950) !important; }
|
|
69
|
-
|
|
70
|
-
.hover\:border-brand-50:hover { border-color: var(--color-brand-50) !important; }
|
|
71
|
-
.hover\:border-brand-100:hover { border-color: var(--color-brand-100) !important; }
|
|
72
|
-
.hover\:border-brand-200:hover { border-color: var(--color-brand-200) !important; }
|
|
73
|
-
.hover\:border-brand-300:hover { border-color: var(--color-brand-300) !important; }
|
|
74
|
-
.hover\:border-brand-400:hover { border-color: var(--color-brand-400) !important; }
|
|
75
|
-
.hover\:border-brand-500:hover { border-color: var(--color-brand-500) !important; }
|
|
76
|
-
.hover\:border-brand-600:hover { border-color: var(--color-brand-600) !important; }
|
|
77
|
-
.hover\:border-brand-700:hover { border-color: var(--color-brand-700) !important; }
|
|
78
|
-
.hover\:border-brand-800:hover { border-color: var(--color-brand-800) !important; }
|
|
79
|
-
.hover\:border-brand-900:hover { border-color: var(--color-brand-900) !important; }
|
|
80
|
-
.hover\:border-brand-950:hover { border-color: var(--color-brand-950) !important; }
|
|
81
|
-
|
|
82
|
-
/* Focus states */
|
|
83
|
-
.focus\:ring-brand-50:focus { --tw-ring-color: var(--color-brand-50) !important; }
|
|
84
|
-
.focus\:ring-brand-100:focus { --tw-ring-color: var(--color-brand-100) !important; }
|
|
85
|
-
.focus\:ring-brand-200:focus { --tw-ring-color: var(--color-brand-200) !important; }
|
|
86
|
-
.focus\:ring-brand-300:focus { --tw-ring-color: var(--color-brand-300) !important; }
|
|
87
|
-
.focus\:ring-brand-400:focus { --tw-ring-color: var(--color-brand-400) !important; }
|
|
88
|
-
.focus\:ring-brand-500:focus { --tw-ring-color: var(--color-brand-500) !important; }
|
|
89
|
-
.focus\:ring-brand-600:focus { --tw-ring-color: var(--color-brand-600) !important; }
|
|
90
|
-
.focus\:ring-brand-700:focus { --tw-ring-color: var(--color-brand-700) !important; }
|
|
91
|
-
.focus\:ring-brand-800:focus { --tw-ring-color: var(--color-brand-800) !important; }
|
|
92
|
-
.focus\:ring-brand-900:focus { --tw-ring-color: var(--color-brand-900) !important; }
|
|
93
|
-
.focus\:ring-brand-950:focus { --tw-ring-color: var(--color-brand-950) !important; }
|
|
94
|
-
|
|
95
|
-
.focus\:border-brand-50:focus { border-color: var(--color-brand-50) !important; }
|
|
96
|
-
.focus\:border-brand-100:focus { border-color: var(--color-brand-100) !important; }
|
|
97
|
-
.focus\:border-brand-200:focus { border-color: var(--color-brand-200) !important; }
|
|
98
|
-
.focus\:border-brand-300:focus { border-color: var(--color-brand-300) !important; }
|
|
99
|
-
.focus\:border-brand-400:focus { border-color: var(--color-brand-400) !important; }
|
|
100
|
-
.focus\:border-brand-500:focus { border-color: var(--color-brand-500) !important; }
|
|
101
|
-
.focus\:border-brand-600:focus { border-color: var(--color-brand-600) !important; }
|
|
102
|
-
.focus\:border-brand-700:focus { border-color: var(--color-brand-700) !important; }
|
|
103
|
-
.focus\:border-brand-800:focus { border-color: var(--color-brand-800) !important; }
|
|
104
|
-
.focus\:border-brand-900:focus { border-color: var(--color-brand-900) !important; }
|
|
105
|
-
.focus\:border-brand-950:focus { border-color: var(--color-brand-950) !important; }
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
[type='text']:focus,
|
|
109
|
-
[type='email']:focus,
|
|
110
|
-
[type='url']:focus,
|
|
111
|
-
[type='password']:focus,
|
|
112
|
-
[type='number']:focus,
|
|
113
|
-
[type='date']:focus,
|
|
114
|
-
[type='datetime-local']:focus,
|
|
115
|
-
[type='month']:focus,
|
|
116
|
-
[type='search']:focus,
|
|
117
|
-
[type='tel']:focus,
|
|
118
|
-
[type='time']:focus,
|
|
119
|
-
[type='week']:focus,
|
|
120
|
-
[multiple]:focus,
|
|
121
|
-
textarea:focus,
|
|
122
|
-
select:focus {
|
|
123
|
-
--tw-ring-color: var(--color-brand-500) !important;
|
|
124
|
-
--tw-ring-opacity: 0.5 !important;
|
|
125
|
-
border-color: var(--color-brand-500) !important;
|
|
126
|
-
outline: 2px solid transparent;
|
|
127
|
-
outline-offset: 2px;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/* Override focus styles for checkboxes and radio buttons */
|
|
131
|
-
[type='checkbox']:focus,
|
|
132
|
-
[type='radio']:focus {
|
|
133
|
-
--tw-ring-color: var(--color-brand-500) !important;
|
|
134
|
-
--tw-ring-opacity: 0.5 !important;
|
|
135
|
-
outline: 2px solid transparent;
|
|
136
|
-
outline-offset: 2px;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/* Override checked styles for checkboxes and radio buttons */
|
|
140
|
-
[type='checkbox']:checked,
|
|
141
|
-
[type='radio']:checked {
|
|
142
|
-
background-color: var(--color-brand-600) !important;
|
|
143
|
-
border-color: var(--color-brand-600) !important;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/* Override focus-visible styles for all form elements */
|
|
147
|
-
[type='text']:focus-visible,
|
|
148
|
-
[type='email']:focus-visible,
|
|
149
|
-
[type='url']:focus-visible,
|
|
150
|
-
[type='password']:focus-visible,
|
|
151
|
-
[type='number']:focus-visible,
|
|
152
|
-
[type='date']:focus-visible,
|
|
153
|
-
[type='datetime-local']:focus-visible,
|
|
154
|
-
[type='month']:focus-visible,
|
|
155
|
-
[type='search']:focus-visible,
|
|
156
|
-
[type='tel']:focus-visible,
|
|
157
|
-
[type='time']:focus-visible,
|
|
158
|
-
[type='week']:focus-visible,
|
|
159
|
-
[multiple]:focus-visible,
|
|
160
|
-
textarea:focus-visible,
|
|
161
|
-
select:focus-visible,
|
|
162
|
-
[type='checkbox']:focus-visible,
|
|
163
|
-
[type='radio']:focus-visible {
|
|
164
|
-
--tw-ring-color: var(--color-brand-500) !important;
|
|
165
|
-
--tw-ring-opacity: 0.5 !important;
|
|
166
|
-
outline: 2px solid transparent;
|
|
167
|
-
outline-offset: 2px;
|
|
168
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
module RivetCms
|
|
2
|
-
module Api
|
|
3
|
-
class DocsController < RivetCms::ApplicationController
|
|
4
|
-
layout false
|
|
5
|
-
|
|
6
|
-
def show
|
|
7
|
-
@schema = RivetCms::OpenApiGenerator.generate
|
|
8
|
-
|
|
9
|
-
respond_to do |format|
|
|
10
|
-
format.html
|
|
11
|
-
format.json { render json: @schema }
|
|
12
|
-
format.yaml { render plain: @schema.to_yaml, content_type: 'application/x-yaml' }
|
|
13
|
-
rescue StandardError => e
|
|
14
|
-
Rails.logger.error "Error generating API documentation: #{e.message}"
|
|
15
|
-
render_error_response(format)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
21
|
-
def render_error_response(format)
|
|
22
|
-
error_schema = {
|
|
23
|
-
openapi: "3.0.1",
|
|
24
|
-
info: {
|
|
25
|
-
title: "API Documentation Temporarily Unavailable",
|
|
26
|
-
version: "1.0.0",
|
|
27
|
-
description: "There was an error generating the API documentation. Please try again later."
|
|
28
|
-
},
|
|
29
|
-
paths: {}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
format.html { render :error, status: :internal_server_error }
|
|
33
|
-
format.json { render json: error_schema, status: :internal_server_error }
|
|
34
|
-
format.yaml { render plain: error_schema.to_yaml, status: :internal_server_error }
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
module RivetCms
|
|
2
|
-
module BrandColorHelper
|
|
3
|
-
# Generate CSS for brand colors based on the primary color
|
|
4
|
-
def brand_color_css
|
|
5
|
-
base_color = "#ff7043"
|
|
6
|
-
|
|
7
|
-
# Generate CSS variables for all the shades
|
|
8
|
-
<<~CSS
|
|
9
|
-
<style id="brand-colors">
|
|
10
|
-
:root {
|
|
11
|
-
--color-brand-50: #{lighten_color(base_color, 0.85)};
|
|
12
|
-
--color-brand-100: #{lighten_color(base_color, 0.7)};
|
|
13
|
-
--color-brand-200: #{lighten_color(base_color, 0.55)};
|
|
14
|
-
--color-brand-300: #{lighten_color(base_color, 0.4)};
|
|
15
|
-
--color-brand-400: #{lighten_color(base_color, 0.2)};
|
|
16
|
-
--color-brand-500: #{lighten_color(base_color, 0.1)};
|
|
17
|
-
--color-brand-600: #{base_color};
|
|
18
|
-
--color-brand-700: #{darken_color(base_color, 0.1)};
|
|
19
|
-
--color-brand-800: #{darken_color(base_color, 0.2)};
|
|
20
|
-
--color-brand-900: #{darken_color(base_color, 0.3)};
|
|
21
|
-
--color-brand-950: #{darken_color(base_color, 0.4)};
|
|
22
|
-
}
|
|
23
|
-
</style>
|
|
24
|
-
CSS
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
private
|
|
28
|
-
|
|
29
|
-
# Simple color manipulation helpers
|
|
30
|
-
def lighten_color(hex_color, amount)
|
|
31
|
-
manipulate_color(hex_color) do |r, g, b|
|
|
32
|
-
[
|
|
33
|
-
[(r + (255 - r) * amount).round, 255].min,
|
|
34
|
-
[(g + (255 - g) * amount).round, 255].min,
|
|
35
|
-
[(b + (255 - b) * amount).round, 255].min
|
|
36
|
-
]
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def darken_color(hex_color, amount)
|
|
41
|
-
manipulate_color(hex_color) do |r, g, b|
|
|
42
|
-
[
|
|
43
|
-
[(r * (1 - amount)).round, 0].max,
|
|
44
|
-
[(g * (1 - amount)).round, 0].max,
|
|
45
|
-
[(b * (1 - amount)).round, 0].max
|
|
46
|
-
]
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def manipulate_color(hex_color)
|
|
51
|
-
hex_color = hex_color.gsub('#', '')
|
|
52
|
-
|
|
53
|
-
# Convert to RGB
|
|
54
|
-
if hex_color.length == 3
|
|
55
|
-
r = hex_color[0].to_i(16) * 17
|
|
56
|
-
g = hex_color[1].to_i(16) * 17
|
|
57
|
-
b = hex_color[2].to_i(16) * 17
|
|
58
|
-
else
|
|
59
|
-
r = hex_color[0..1].to_i(16)
|
|
60
|
-
g = hex_color[2..3].to_i(16)
|
|
61
|
-
b = hex_color[4..5].to_i(16)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# Apply transformation
|
|
65
|
-
new_r, new_g, new_b = yield(r, g, b)
|
|
66
|
-
|
|
67
|
-
# Convert back to hex
|
|
68
|
-
"#%02x%02x%02x" % [new_r, new_g, new_b]
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
module RivetCms
|
|
2
|
-
module FlashHelper
|
|
3
|
-
def flash_class_for(type)
|
|
4
|
-
case type.to_sym
|
|
5
|
-
when :notice, :success
|
|
6
|
-
"bg-green-50"
|
|
7
|
-
when :error, :alert
|
|
8
|
-
"bg-red-50"
|
|
9
|
-
when :warning
|
|
10
|
-
"bg-yellow-50"
|
|
11
|
-
else
|
|
12
|
-
"bg-gray-50"
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def flash_icon_for(type)
|
|
17
|
-
case type.to_sym
|
|
18
|
-
when :notice, :success
|
|
19
|
-
content_tag(:svg, class: "h-5 w-5 text-green-400", viewBox: "0 0 20 20", fill: "currentColor") do
|
|
20
|
-
content_tag(:path, nil, fill_rule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z", clip_rule: "evenodd")
|
|
21
|
-
end
|
|
22
|
-
when :error, :alert
|
|
23
|
-
content_tag(:svg, class: "h-5 w-5 text-red-400", viewBox: "0 0 20 20", fill: "currentColor") do
|
|
24
|
-
content_tag(:path, nil, 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")
|
|
25
|
-
end
|
|
26
|
-
when :warning
|
|
27
|
-
content_tag(:svg, class: "h-5 w-5 text-yellow-400", viewBox: "0 0 20 20", fill: "currentColor") do
|
|
28
|
-
content_tag(:path, nil, fill_rule: "evenodd", d: "M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z", clip_rule: "evenodd")
|
|
29
|
-
end
|
|
30
|
-
else
|
|
31
|
-
content_tag(:svg, class: "h-5 w-5 text-gray-400", viewBox: "0 0 20 20", fill: "currentColor") do
|
|
32
|
-
content_tag(:path, nil, 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")
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
module RivetCms
|
|
2
|
-
module SignOutHelper
|
|
3
|
-
# Returns the sign-out path for the application.
|
|
4
|
-
# Uses RivetCmsAuth’s auth_sign_out_path if available, otherwise falls back to the configured path or root.
|
|
5
|
-
def rivet_sign_out_path
|
|
6
|
-
config = RivetCms.configuration
|
|
7
|
-
return config.sign_out_path.call if config.sign_out_path.respond_to?(:call)
|
|
8
|
-
config.sign_out_path || "/"
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { Controller } from "@hotwired/stimulus"
|
|
2
|
-
import pluralize from "pluralize"
|
|
3
|
-
|
|
4
|
-
export default class extends Controller {
|
|
5
|
-
static targets = ["name", "slug", "isSingle"]
|
|
6
|
-
|
|
7
|
-
connect() {
|
|
8
|
-
this.nameTarget.addEventListener("input", this.updateSlug.bind(this))
|
|
9
|
-
this.isSingleTarget.addEventListener("change", this.updateSlug.bind(this))
|
|
10
|
-
this.lastGeneratedSlug = this.slugTarget.value
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
updateSlug() {
|
|
14
|
-
const name = this.nameTarget.value.trim()
|
|
15
|
-
if (!name) {
|
|
16
|
-
this.slugTarget.value = ""
|
|
17
|
-
return
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
let slug = this.generateSlug(name)
|
|
21
|
-
if (!slug) {
|
|
22
|
-
this.slugTarget.value = ""
|
|
23
|
-
return
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const isSingle = this.isSingleTarget.checked
|
|
27
|
-
if (isSingle && pluralize.isPlural(slug)) {
|
|
28
|
-
slug = pluralize.singular(slug)
|
|
29
|
-
} else if (!isSingle && !pluralize.isPlural(slug)) {
|
|
30
|
-
slug = pluralize(slug)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (slug !== this.lastGeneratedSlug) {
|
|
34
|
-
this.slugTarget.value = slug
|
|
35
|
-
this.lastGeneratedSlug = slug
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
generateSlug(text) {
|
|
40
|
-
return text
|
|
41
|
-
.toLowerCase()
|
|
42
|
-
.replace(/[\s_]+/g, "-") // Spaces or underscores to hyphen
|
|
43
|
-
.replace(/[^a-z0-9-]/g, "") // Keep letters, numbers, hyphens
|
|
44
|
-
.replace(/-+/g, "-") // Collapse hyphens
|
|
45
|
-
.replace(/^-|-$/g, "") // Trim leading/trailing hyphens
|
|
46
|
-
.trim()
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
disconnect() {
|
|
50
|
-
this.nameTarget.removeEventListener("input", this.updateSlug.bind(this))
|
|
51
|
-
this.isSingleTarget.removeEventListener("change", this.updateSlug.bind(this))
|
|
52
|
-
}
|
|
53
|
-
}
|