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
data/app/javascript/rivet_cms.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import "@hotwired/turbo-rails"
|
|
2
|
-
import { Application } from "@hotwired/stimulus"
|
|
3
|
-
import FieldLayoutController from "./controllers/field_layout_controller"
|
|
4
|
-
import ContentTypeFormController from "./controllers/content_type_form_controller"
|
|
5
|
-
|
|
6
|
-
const application = Application.start()
|
|
7
|
-
|
|
8
|
-
// Configure Stimulus development experience
|
|
9
|
-
application.debug = false
|
|
10
|
-
window.Stimulus = application
|
|
11
|
-
|
|
12
|
-
// Register controllers
|
|
13
|
-
application.register("field-layout", FieldLayoutController)
|
|
14
|
-
application.register("content-type-form", ContentTypeFormController)
|
|
15
|
-
document.addEventListener("turbo:load", function(event) {
|
|
16
|
-
// Mobile menu toggle
|
|
17
|
-
const mobileMenuButton = document.querySelector('[aria-controls="mobile-menu"]')
|
|
18
|
-
const mobileMenu = document.getElementById('mobile-menu')
|
|
19
|
-
|
|
20
|
-
if (mobileMenuButton && mobileMenu) {
|
|
21
|
-
mobileMenuButton.addEventListener('click', () => {
|
|
22
|
-
const expanded = mobileMenuButton.getAttribute('aria-expanded') === 'true'
|
|
23
|
-
mobileMenuButton.setAttribute('aria-expanded', !expanded)
|
|
24
|
-
mobileMenu.classList.toggle('hidden')
|
|
25
|
-
})
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
export { application }
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>RivetCMS - API Documentation</title>
|
|
5
|
-
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
-
<%= stylesheet_link_tag "rivet_cms", "data-turbo-track": "reload", time: Time.now.to_i %>
|
|
7
|
-
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css">
|
|
8
|
-
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
9
|
-
<style>
|
|
10
|
-
.swagger-ui {
|
|
11
|
-
margin-top: 1rem;
|
|
12
|
-
}
|
|
13
|
-
.swagger-ui .topbar {
|
|
14
|
-
display: none;
|
|
15
|
-
}
|
|
16
|
-
</style>
|
|
17
|
-
</head>
|
|
18
|
-
<body class="bg-gray-50">
|
|
19
|
-
<div class="bg-white border-b border-gray-200 sticky top-0 z-50">
|
|
20
|
-
<nav class="flex h-12">
|
|
21
|
-
<%= link_to root_path, class: "inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-900" do %>
|
|
22
|
-
<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-dashboard mr-2"><rect width="7" height="9" x="3" y="3" rx="1"/><rect width="7" height="5" x="14" y="3" rx="1"/><rect width="7" height="9" x="14" y="12" rx="1"/><rect width="7" height="5" x="3" y="16" rx="1"/></svg>
|
|
23
|
-
Dashboard
|
|
24
|
-
<% end %>
|
|
25
|
-
</nav>
|
|
26
|
-
</div>
|
|
27
|
-
<div id="swagger-ui"></div>
|
|
28
|
-
<script>
|
|
29
|
-
window.onload = function() {
|
|
30
|
-
SwaggerUIBundle({
|
|
31
|
-
url: "<%= api_docs_path(format: :yaml) %>",
|
|
32
|
-
dom_id: '#swagger-ui',
|
|
33
|
-
deepLinking: true,
|
|
34
|
-
presets: [
|
|
35
|
-
SwaggerUIBundle.presets.apis,
|
|
36
|
-
SwaggerUIBundle.SwaggerUIStandalonePreset
|
|
37
|
-
],
|
|
38
|
-
layout: "BaseLayout",
|
|
39
|
-
docExpansion: 'list',
|
|
40
|
-
defaultModelsExpandDepth: 1,
|
|
41
|
-
defaultModelExpandDepth: 1,
|
|
42
|
-
displayRequestDuration: true
|
|
43
|
-
});
|
|
44
|
-
};
|
|
45
|
-
</script>
|
|
46
|
-
</body>
|
|
47
|
-
</html>
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
<%= form_with(model: content_type, class: "space-y-8", id: "content_type_form", data: { controller: "content-type-form" }) do |form| %>
|
|
2
|
-
<div class="bg-white shadow-md rounded-lg overflow-hidden border border-gray-100">
|
|
3
|
-
<div class="px-6 py-5 border-b border-gray-200 bg-gray-50">
|
|
4
|
-
<h3 class="text-lg font-medium leading-6 text-gray-900">Content Type Details</h3>
|
|
5
|
-
<p class="mt-1 text-sm text-gray-500">
|
|
6
|
-
Define the basic information for your content type.
|
|
7
|
-
</p>
|
|
8
|
-
</div>
|
|
9
|
-
|
|
10
|
-
<div class="px-6 py-6 space-y-8">
|
|
11
|
-
<div>
|
|
12
|
-
<%= form.label :name, class: "block text-sm font-medium text-gray-700 mb-1" %>
|
|
13
|
-
<div class="relative mt-1 group">
|
|
14
|
-
<%= form.text_field :name,
|
|
15
|
-
class: "block w-full pl-10 px-4 py-3 rounded-md #{content_type.errors[:name].any? ? 'text-red-800 placeholder-red-300 focus:ring-1 focus:ring-red-500 focus:outline-none' : 'focus:ring-1 border-gray-300 focus:ring-gray-500 focus:outline-none'} shadow-sm sm:text-sm transition-all duration-200",
|
|
16
|
-
placeholder: "e.g. Article, Product, Homepage",
|
|
17
|
-
data: { content_type_form_target: "name" } %>
|
|
18
|
-
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
|
19
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 #{content_type.errors[:name].any? ? 'text-red-400' : 'text-gray-400 group-hover:text-brand-500'} transition-colors duration-200" viewBox="0 0 20 20" fill="currentColor">
|
|
20
|
-
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z" />
|
|
21
|
-
<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" />
|
|
22
|
-
</svg>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
<% if content_type.errors[:name].any? %>
|
|
26
|
-
<p class="mt-2 text-sm text-red-600">Name <%= content_type.errors[:name].join(", ") %></p>
|
|
27
|
-
<% else %>
|
|
28
|
-
<p class="mt-2 text-sm text-gray-500">A human-readable name for your content type.</p>
|
|
29
|
-
<% end %>
|
|
30
|
-
</div>
|
|
31
|
-
|
|
32
|
-
<div>
|
|
33
|
-
<%= form.label :slug, class: "block text-sm font-medium text-gray-700 mb-1" %>
|
|
34
|
-
<div class="relative mt-1 group">
|
|
35
|
-
<%= form.text_field :slug,
|
|
36
|
-
class: "block w-full pl-10 px-4 py-3 rounded-md #{content_type.errors[:slug].any? ? 'text-red-800 placeholder-red-300 focus:ring-1 focus:ring-red-500 focus:outline-none' : 'focus:ring-1 focus:ring-gray-500 focus:outline-none'} shadow-sm sm:text-sm font-mono transition-all duration-200",
|
|
37
|
-
placeholder: "e.g. article, product, homepage",
|
|
38
|
-
data: { content_type_form_target: "slug" } %>
|
|
39
|
-
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
|
40
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 #{content_type.errors[:slug].any? ? 'text-red-400' : 'text-gray-400 group-hover:text-brand-500'} transition-colors duration-200" viewBox="0 0 20 20" fill="currentColor">
|
|
41
|
-
<path fill-rule="evenodd" d="M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z" clip-rule="evenodd" />
|
|
42
|
-
</svg>
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
<% if content_type.errors[:slug].any? %>
|
|
46
|
-
<p class="mt-2 text-sm text-red-600">Slug <%= content_type.errors[:slug].join(", ") %></p>
|
|
47
|
-
<% else %>
|
|
48
|
-
<p class="mt-2 text-sm text-gray-500">The API identifier for this content type. Used in API routes.</p>
|
|
49
|
-
<% end %>
|
|
50
|
-
</div>
|
|
51
|
-
|
|
52
|
-
<div>
|
|
53
|
-
<%= form.label :description, class: "block text-sm font-medium text-gray-700 mb-1" %>
|
|
54
|
-
<div class="relative mt-1 group">
|
|
55
|
-
<%= form.text_area :description,
|
|
56
|
-
rows: 3,
|
|
57
|
-
class: "block w-full pl-10 px-4 py-3 rounded-md #{content_type.errors[:description].any? ? 'border-red-300 text-red-900 placeholder-red-300 focus:ring-red-500 focus:border-red-500' : 'border-gray-300 focus:ring-brand-500 focus:border-brand-500'} shadow-sm sm:text-sm transition-all duration-200 group-hover:border-brand-300",
|
|
58
|
-
placeholder: "Description of this content type" %>
|
|
59
|
-
<div class="absolute top-3 left-0 pl-3 flex items-start pointer-events-none">
|
|
60
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 #{content_type.errors[:description].any? ? 'text-red-400' : 'text-gray-400 group-hover:text-brand-500'} transition-colors duration-200" viewBox="0 0 20 20" fill="currentColor">
|
|
61
|
-
<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" />
|
|
62
|
-
</svg>
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
<% if content_type.errors[:description].any? %>
|
|
66
|
-
<p class="mt-2 text-sm text-red-600">Description <%= content_type.errors[:description].join(", ") %></p>
|
|
67
|
-
<% else %>
|
|
68
|
-
<p class="mt-2 text-sm text-gray-500">Optional description for this content type.</p>
|
|
69
|
-
<% end %>
|
|
70
|
-
</div>
|
|
71
|
-
|
|
72
|
-
<div class="pt-2">
|
|
73
|
-
<div class="relative flex items-start">
|
|
74
|
-
<div class="flex items-center h-5">
|
|
75
|
-
<%= form.check_box :is_single,
|
|
76
|
-
class: "h-5 w-5 rounded #{content_type.errors[:is_single].any? ? 'border-red-300 text-red-600 focus:ring-red-500' : 'border-gray-300 text-brand-600 focus:ring-brand-500'} transition-all duration-200",
|
|
77
|
-
data: { content_type_form_target: "isSingle" } %>
|
|
78
|
-
</div>
|
|
79
|
-
<div class="ml-3 text-sm">
|
|
80
|
-
<%= form.label :is_single, "Single Type", class: "font-medium text-gray-700" %>
|
|
81
|
-
<% if content_type.errors[:is_single].any? %>
|
|
82
|
-
<p class="text-red-600">Single Type <%= content_type.errors[:is_single].join(", ") %></p>
|
|
83
|
-
<% else %>
|
|
84
|
-
<p class="text-gray-500">If checked, this will be a single type (one entry). If unchecked, it will be a collection type (multiple entries).</p>
|
|
85
|
-
<% end %>
|
|
86
|
-
</div>
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
|
|
92
|
-
<div class="flex justify-end pt-4">
|
|
93
|
-
<%= link_to content_types_path, class: "rounded-md border border-gray-300 bg-white py-3 px-5 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 %>
|
|
94
|
-
Cancel
|
|
95
|
-
<% end %>
|
|
96
|
-
<%= form.submit class: "ml-3 inline-flex items-center rounded-md bg-brand-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-brand-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-600 cursor-pointer" %>
|
|
97
|
-
</div>
|
|
98
|
-
<% end %>
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
2
|
-
<div class="mb-8">
|
|
3
|
-
<div class="flex items-center justify-between">
|
|
4
|
-
<div>
|
|
5
|
-
<h1 class="text-2xl font-bold text-gray-900">Edit Content Type</h1>
|
|
6
|
-
<p class="mt-1 text-sm text-gray-500">Update the details for "<%= @content_type.name %>"</p>
|
|
7
|
-
</div>
|
|
8
|
-
<div class="flex space-x-3">
|
|
9
|
-
<%= link_to content_type_path(@content_type), class: "inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-brand-500 transition-all duration-200" do %>
|
|
10
|
-
<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">
|
|
11
|
-
<path fill-rule="evenodd" d="M6.672 1.911a1 1 0 10-1.932.518l.259.966a1 1 0 001.932-.518l-.26-.966zM2.429 4.74a1 1 0 10-.517 1.932l.966.259a1 1 0 00.517-1.932l-.966-.26zm8.814-.569a1 1 0 00-1.415-1.414l-.707.707a1 1 0 101.415 1.415l.707-.708zm-7.071 7.072l.707-.707A1 1 0 003.465 9.12l-.708.707a1 1 0 001.415 1.415zm3.2-5.171a1 1 0 00-1.3 1.3l4 10a1 1 0 001.823.075l1.38-2.759 3.018 3.02a1 1 0 001.414-1.415l-3.019-3.02 2.76-1.379a1 1 0 00-.076-1.822l-10-4z" clip-rule="evenodd" />
|
|
12
|
-
</svg>
|
|
13
|
-
View
|
|
14
|
-
<% end %>
|
|
15
|
-
|
|
16
|
-
<%= link_to content_types_path, class: "inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-brand-500 transition-all duration-200" do %>
|
|
17
|
-
<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">
|
|
18
|
-
<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" />
|
|
19
|
-
</svg>
|
|
20
|
-
Back
|
|
21
|
-
<% end %>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
|
|
26
|
-
<%= render "form", content_type: @content_type %>
|
|
27
|
-
</div>
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
2
|
-
<div class="sm:flex sm:items-center mb-8">
|
|
3
|
-
<div class="sm:flex-auto">
|
|
4
|
-
<h1 class="text-2xl font-bold text-gray-900">Content Types</h1>
|
|
5
|
-
<p class="mt-2 text-sm text-gray-500">
|
|
6
|
-
A list of all the content types in your headless CMS.
|
|
7
|
-
</p>
|
|
8
|
-
</div>
|
|
9
|
-
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
|
|
10
|
-
<%= link_to new_content_type_path, class: "inline-flex items-center rounded-md border border-transparent bg-brand-600 px-4 py-2 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" do %>
|
|
11
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus -ml-1 mr-2 h-5 w-5">
|
|
12
|
-
<path d="M5 12h14" />
|
|
13
|
-
<path d="M12 5v14" />
|
|
14
|
-
</svg>
|
|
15
|
-
New Content Type
|
|
16
|
-
<% end %>
|
|
17
|
-
</div>
|
|
18
|
-
</div>
|
|
19
|
-
|
|
20
|
-
<div class="bg-white shadow overflow-hidden sm:rounded-lg border border-gray-100">
|
|
21
|
-
<% if @content_types.any? %>
|
|
22
|
-
<div class="overflow-x-auto">
|
|
23
|
-
<table class="min-w-full divide-y divide-gray-200">
|
|
24
|
-
<thead class="bg-gray-50">
|
|
25
|
-
<tr>
|
|
26
|
-
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Name</th>
|
|
27
|
-
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Slug</th>
|
|
28
|
-
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
|
|
29
|
-
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Items</th>
|
|
30
|
-
<th scope="col" class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
|
|
31
|
-
</tr>
|
|
32
|
-
</thead>
|
|
33
|
-
<tbody class="bg-white divide-y divide-gray-200">
|
|
34
|
-
<% @content_types.each do |content_type| %>
|
|
35
|
-
<tr class="hover:bg-gray-50 transition-all duration-150">
|
|
36
|
-
<td class="px-6 py-4 whitespace-nowrap">
|
|
37
|
-
<div class="flex items-center">
|
|
38
|
-
<div class="flex-shrink-0 h-10 w-10 flex items-center justify-center rounded-md bg-brand-50 text-brand-600 border border-brand-100">
|
|
39
|
-
<% if content_type.is_single %>
|
|
40
|
-
<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-file-text h-6 w-6">
|
|
41
|
-
<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" />
|
|
42
|
-
<polyline points="14 2 14 8 20 8" />
|
|
43
|
-
<line x1="16" x2="8" y1="13" y2="13" />
|
|
44
|
-
<line x1="16" x2="8" y1="17" y2="17" />
|
|
45
|
-
<line x1="10" x2="8" y1="9" y2="9" />
|
|
46
|
-
</svg>
|
|
47
|
-
<% else %>
|
|
48
|
-
<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-layers h-6 w-6">
|
|
49
|
-
<polygon points="12 2 2 7 12 12 22 7 12 2" />
|
|
50
|
-
<polyline points="2 17 12 22 22 17" />
|
|
51
|
-
<polyline points="2 12 12 17 22 12" />
|
|
52
|
-
</svg>
|
|
53
|
-
<% end %>
|
|
54
|
-
</div>
|
|
55
|
-
<div class="ml-4">
|
|
56
|
-
<div class="text-sm font-medium text-gray-900">
|
|
57
|
-
<%= link_to content_type.name, content_type_path(content_type), class: "hover:text-brand-600 transition-colors duration-150 border-b border-transparent hover:border-brand-600" %>
|
|
58
|
-
</div>
|
|
59
|
-
<% if content_type.description.present? %>
|
|
60
|
-
<div class="text-sm text-gray-500 truncate max-w-xs">
|
|
61
|
-
<%= content_type.description %>
|
|
62
|
-
</div>
|
|
63
|
-
<% end %>
|
|
64
|
-
</div>
|
|
65
|
-
</div>
|
|
66
|
-
</td>
|
|
67
|
-
<td class="px-6 py-4 whitespace-nowrap">
|
|
68
|
-
<div class="text-sm font-mono text-gray-900 bg-gray-50 px-2 py-1 rounded-sm border border-gray-100 inline-block"><%= content_type.slug %></div>
|
|
69
|
-
</td>
|
|
70
|
-
<td class="px-6 py-4 whitespace-nowrap">
|
|
71
|
-
<% if content_type.is_single %>
|
|
72
|
-
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-amber-100 text-amber-800 border border-amber-200">
|
|
73
|
-
Single Type
|
|
74
|
-
</span>
|
|
75
|
-
<% else %>
|
|
76
|
-
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-teal-100 text-teal-800 border border-teal-200">
|
|
77
|
-
Collection
|
|
78
|
-
</span>
|
|
79
|
-
<% end %>
|
|
80
|
-
</td>
|
|
81
|
-
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
|
82
|
-
<span class="bg-gray-100 text-gray-700 px-2 py-1 rounded-full text-xs font-medium"><%= content_type.contents.count %></span>
|
|
83
|
-
</td>
|
|
84
|
-
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
85
|
-
<div class="flex justify-end space-x-2">
|
|
86
|
-
<%= link_to content_type_path(content_type), class: "text-brand-500 hover:text-brand-700 transition-colors duration-150 p-1 hover:bg-brand-100 rounded-full", title: "View" do %>
|
|
87
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-eye h-5 w-5">
|
|
88
|
-
<path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" />
|
|
89
|
-
<circle cx="12" cy="12" r="3" />
|
|
90
|
-
</svg>
|
|
91
|
-
<% end %>
|
|
92
|
-
|
|
93
|
-
<%= link_to content_type_fields_path(content_type), class: "text-gray-500 hover:text-gray-700 transition-colors duration-150 p-1 hover:bg-gray-200 rounded-full", title: "Structure" do %>
|
|
94
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layout-grid h-5 w-5">
|
|
95
|
-
<path d="M12 3v18"/><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 9h18"/><path d="M3 15h18"/>
|
|
96
|
-
</svg>
|
|
97
|
-
<% end %>
|
|
98
|
-
|
|
99
|
-
<%= link_to edit_content_type_path(content_type), class: "text-amber-500 hover:text-amber-700 transition-colors duration-150 p-1 hover:bg-amber-100 rounded-full", title: "Edit" do %>
|
|
100
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-pencil h-5 w-5">
|
|
101
|
-
<path d="M17 3a2.85 2.85 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" />
|
|
102
|
-
<path d="m15 5 4 4" />
|
|
103
|
-
</svg>
|
|
104
|
-
<% end %>
|
|
105
|
-
|
|
106
|
-
<%= button_to content_type_path(content_type), method: :delete, class: "text-red-500 hover:text-red-700 transition-colors duration-150 p-1 hover:bg-red-100 rounded-full", title: "Delete", form: { data: { turbo_confirm: "Are you sure you want to delete this content type? This will also delete all contents associated with it." } } do %>
|
|
107
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash-2 h-5 w-5">
|
|
108
|
-
<path d="M3 6h18" />
|
|
109
|
-
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" />
|
|
110
|
-
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" />
|
|
111
|
-
<line x1="10" x2="10" y1="11" y2="17" />
|
|
112
|
-
<line x1="14" x2="14" y1="11" y2="17" />
|
|
113
|
-
</svg>
|
|
114
|
-
<% end %>
|
|
115
|
-
</div>
|
|
116
|
-
</td>
|
|
117
|
-
</tr>
|
|
118
|
-
<% end %>
|
|
119
|
-
</tbody>
|
|
120
|
-
</table>
|
|
121
|
-
</div>
|
|
122
|
-
<% else %>
|
|
123
|
-
<div class="text-center py-16 px-6">
|
|
124
|
-
<div class="relative mx-auto h-24 w-24 text-gray-400 bg-gray-50 rounded-full border border-gray-100 flex items-center justify-center">
|
|
125
|
-
<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-layers h-12 w-12">
|
|
126
|
-
<polygon points="12 2 2 7 12 12 22 7 12 2" />
|
|
127
|
-
<polyline points="2 17 12 22 22 17" />
|
|
128
|
-
<polyline points="2 12 12 17 22 12" />
|
|
129
|
-
</svg>
|
|
130
|
-
<div class="absolute -top-1 -right-1 h-6 w-6 bg-brand-100 rounded-full border border-brand-200 flex items-center justify-center">
|
|
131
|
-
<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-plus h-4 w-4 text-brand-600">
|
|
132
|
-
<path d="M5 12h14" />
|
|
133
|
-
<path d="M12 5v14" />
|
|
134
|
-
</svg>
|
|
135
|
-
</div>
|
|
136
|
-
</div>
|
|
137
|
-
<h3 class="mt-4 text-sm font-medium text-gray-900">No content types</h3>
|
|
138
|
-
<p class="mt-1 text-sm text-gray-500">Get started by creating a new content type.</p>
|
|
139
|
-
<div class="mt-6">
|
|
140
|
-
<%= link_to new_content_type_path, class: "inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md 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 %>
|
|
141
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus -ml-1 mr-2 h-5 w-5">
|
|
142
|
-
<path d="M5 12h14" />
|
|
143
|
-
<path d="M12 5v14" />
|
|
144
|
-
</svg>
|
|
145
|
-
New Content Type
|
|
146
|
-
<% end %>
|
|
147
|
-
</div>
|
|
148
|
-
</div>
|
|
149
|
-
<% end %>
|
|
150
|
-
</div>
|
|
151
|
-
</div>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
2
|
-
<div class="mb-8">
|
|
3
|
-
<div class="flex items-center justify-between">
|
|
4
|
-
<div>
|
|
5
|
-
<h1 class="text-2xl font-bold text-gray-900">New Content Type</h1>
|
|
6
|
-
</div>
|
|
7
|
-
<div>
|
|
8
|
-
<%= link_to content_types_path, class: "inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-brand-500 transition-all duration-200" do %>
|
|
9
|
-
<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">
|
|
10
|
-
<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" />
|
|
11
|
-
</svg>
|
|
12
|
-
Back to Content Types
|
|
13
|
-
<% end %>
|
|
14
|
-
</div>
|
|
15
|
-
</div>
|
|
16
|
-
</div>
|
|
17
|
-
|
|
18
|
-
<%= render "form", content_type: @content_type %>
|
|
19
|
-
</div>
|
|
@@ -1,147 +0,0 @@
|
|
|
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"><%= @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
|
-
API Endpoint: <code class="bg-gray-50 px-3 py-1 rounded font-mono text-sm border border-gray-100"><%= @content_type.is_single ? "/api/v1/#{@content_type.slug}" : "/api/v1/#{@content_type.slug}" %></code>
|
|
12
|
-
</p>
|
|
13
|
-
<% if @content_type.description.present? %>
|
|
14
|
-
<p class="mt-2 text-sm text-gray-500"><%= @content_type.description %></p>
|
|
15
|
-
<% end %>
|
|
16
|
-
</div>
|
|
17
|
-
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
|
|
18
|
-
<div class="flex space-x-3">
|
|
19
|
-
<%= link_to content_types_path, 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 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 transition-all duration-200" do %>
|
|
20
|
-
<svg class="-ml-1 mr-2 h-5 w-5 text-gray-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
|
21
|
-
<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" />
|
|
22
|
-
</svg>
|
|
23
|
-
Back
|
|
24
|
-
<% end %>
|
|
25
|
-
<%= link_to edit_content_type_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 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 transition-all duration-200" do %>
|
|
26
|
-
<svg class="-ml-1 mr-2 h-5 w-5 text-gray-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
|
27
|
-
<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" />
|
|
28
|
-
</svg>
|
|
29
|
-
Edit Content Type
|
|
30
|
-
<% end %>
|
|
31
|
-
<% if @content_type.fields.any? %>
|
|
32
|
-
<%= link_to "#", class: "inline-flex items-center rounded-md border border-transparent bg-brand-600 px-4 py-2 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" do %>
|
|
33
|
-
<svg class="-ml-1 mr-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
|
34
|
-
<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" />
|
|
35
|
-
</svg>
|
|
36
|
-
New <%= @content_type.name.singularize %>
|
|
37
|
-
<% end %>
|
|
38
|
-
<% end %>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
<!-- Content Items -->
|
|
44
|
-
<div class="bg-white shadow-md rounded-lg overflow-hidden border border-gray-100">
|
|
45
|
-
<div class="px-6 py-5 border-b border-gray-200 bg-gray-50">
|
|
46
|
-
<div class="flex justify-between items-center">
|
|
47
|
-
<h2 class="text-lg font-medium text-gray-900">
|
|
48
|
-
<%= @content_type.is_single ? @content_type.name : "#{@content_type.name} Items" %>
|
|
49
|
-
</h2>
|
|
50
|
-
<span class="bg-gray-100 text-gray-700 px-2 py-1 rounded-full text-xs font-medium border border-gray-200"><%= pluralize(@contents.count, 'item') %></span>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
|
|
54
|
-
<% if @contents.any? %>
|
|
55
|
-
<div class="overflow-x-auto">
|
|
56
|
-
<table class="min-w-full divide-y divide-gray-200">
|
|
57
|
-
<thead class="bg-gray-50">
|
|
58
|
-
<tr>
|
|
59
|
-
<th scope="col" class="py-3.5 pl-6 pr-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Title</th>
|
|
60
|
-
<th scope="col" class="px-3 py-3.5 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
|
|
61
|
-
<th scope="col" class="px-3 py-3.5 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Created</th>
|
|
62
|
-
<th scope="col" class="px-3 py-3.5 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Updated</th>
|
|
63
|
-
<th scope="col" class="relative py-3.5 pl-3 pr-6 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
64
|
-
Actions
|
|
65
|
-
</th>
|
|
66
|
-
</tr>
|
|
67
|
-
</thead>
|
|
68
|
-
<tbody class="divide-y divide-gray-200 bg-white">
|
|
69
|
-
<% @contents.each do |content| %>
|
|
70
|
-
<tr class="hover:bg-gray-50 transition-all duration-150">
|
|
71
|
-
<td class="whitespace-nowrap py-4 pl-6 pr-3 text-sm font-medium text-gray-900"><%= content.title %></td>
|
|
72
|
-
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
|
73
|
-
<% if content.status == 'published' %>
|
|
74
|
-
<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium bg-brand-100 text-brand-800 border border-brand-200">
|
|
75
|
-
Published
|
|
76
|
-
</span>
|
|
77
|
-
<% elsif content.status == 'draft' %>
|
|
78
|
-
<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium bg-amber-100 text-amber-800 border border-amber-200">
|
|
79
|
-
Draft
|
|
80
|
-
</span>
|
|
81
|
-
<% else %>
|
|
82
|
-
<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium bg-gray-100 text-gray-800 border border-gray-200">
|
|
83
|
-
<%= content.status.capitalize %>
|
|
84
|
-
</span>
|
|
85
|
-
<% end %>
|
|
86
|
-
</td>
|
|
87
|
-
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"><%= content.created_at.strftime("%b %d, %Y") %></td>
|
|
88
|
-
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"><%= content.updated_at.strftime("%b %d, %Y") %></td>
|
|
89
|
-
<td class="relative whitespace-nowrap py-4 pl-3 pr-6 text-right text-sm font-medium">
|
|
90
|
-
<div class="flex justify-end space-x-2">
|
|
91
|
-
<%= link_to "#", class: "text-brand-600 hover:text-brand-900 transition-colors duration-150 p-1 hover:bg-brand-50 rounded-full" do %>
|
|
92
|
-
<span class="sr-only">Edit</span>
|
|
93
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
|
94
|
-
<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" />
|
|
95
|
-
</svg>
|
|
96
|
-
<% end %>
|
|
97
|
-
<%= button_to "#", method: :delete, class: "text-red-600 hover:text-red-900 transition-colors duration-150 p-1 hover:bg-red-50 rounded-full", form: { data: { turbo_confirm: "Are you sure? This will permanently delete this content." } } do %>
|
|
98
|
-
<span class="sr-only">Delete</span>
|
|
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
|
-
</td>
|
|
105
|
-
</tr>
|
|
106
|
-
<% end %>
|
|
107
|
-
</tbody>
|
|
108
|
-
</table>
|
|
109
|
-
</div>
|
|
110
|
-
<% else %>
|
|
111
|
-
<div class="text-center py-16 px-6">
|
|
112
|
-
<div class="relative mx-auto h-24 w-24 text-gray-400 bg-gray-50 rounded-full border border-gray-100 flex items-center justify-center">
|
|
113
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
114
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
115
|
-
</svg>
|
|
116
|
-
<div class="absolute -top-1 -right-1 h-6 w-6 bg-brand-100 rounded-full border border-brand-200 flex items-center justify-center">
|
|
117
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-brand-600" 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
|
-
</div>
|
|
121
|
-
</div>
|
|
122
|
-
<h3 class="mt-4 text-sm font-medium text-gray-900">No content</h3>
|
|
123
|
-
<% if @content_type.fields.any? %>
|
|
124
|
-
<p class="mt-1 text-sm text-gray-500">Get started by creating content for this content type.</p>
|
|
125
|
-
<div class="mt-6">
|
|
126
|
-
<%= link_to "#", class: "inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md 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 %>
|
|
127
|
-
<svg class="-ml-1 mr-2 h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
|
128
|
-
<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" />
|
|
129
|
-
</svg>
|
|
130
|
-
New <%= @content_type.name.singularize %>
|
|
131
|
-
<% end %>
|
|
132
|
-
</div>
|
|
133
|
-
<% else %>
|
|
134
|
-
<p class="mt-1 text-sm text-gray-500">You must add at least one field to this content type before you can create any content.</p>
|
|
135
|
-
<div class="mt-6">
|
|
136
|
-
<%= link_to "#", class: "inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md 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 %>
|
|
137
|
-
<svg class="-ml-1 mr-2 h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
|
138
|
-
<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" />
|
|
139
|
-
</svg>
|
|
140
|
-
Add Field
|
|
141
|
-
<% end %>
|
|
142
|
-
</div>
|
|
143
|
-
<% end %>
|
|
144
|
-
</div>
|
|
145
|
-
<% end %>
|
|
146
|
-
</div>
|
|
147
|
-
</div>
|