panda_cms 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +71 -0
- data/Rakefile +8 -0
- data/app/assets/builds/panda_cms.css +1 -0
- data/app/assets/config/panda_cms_manifest.js +1 -0
- data/app/assets/stylesheets/panda_cms/application.tailwind.css +61 -0
- data/app/builders/panda_cms/form_builder.rb +118 -0
- data/app/components/panda_cms/admin/button_component.rb +65 -0
- data/app/components/panda_cms/admin/container_component.html.erb +13 -0
- data/app/components/panda_cms/admin/container_component.rb +11 -0
- data/app/components/panda_cms/admin/flash_message_component.html.erb +30 -0
- data/app/components/panda_cms/admin/flash_message_component.rb +44 -0
- data/app/components/panda_cms/admin/heading_component.rb +43 -0
- data/app/components/panda_cms/admin/panel_component.html.erb +7 -0
- data/app/components/panda_cms/admin/panel_component.rb +11 -0
- data/app/components/panda_cms/admin/slideover_component.html.erb +9 -0
- data/app/components/panda_cms/admin/slideover_component.rb +13 -0
- data/app/components/panda_cms/admin/statistics_component.html.erb +4 -0
- data/app/components/panda_cms/admin/statistics_component.rb +15 -0
- data/app/components/panda_cms/admin/tab_bar_component.html.erb +35 -0
- data/app/components/panda_cms/admin/tab_bar_component.rb +13 -0
- data/app/components/panda_cms/admin/table_component.html.erb +21 -0
- data/app/components/panda_cms/admin/table_component.rb +43 -0
- data/app/components/panda_cms/admin/tag_component.rb +33 -0
- data/app/components/panda_cms/admin/user_activity_component.html.erb +5 -0
- data/app/components/panda_cms/admin/user_activity_component.rb +19 -0
- data/app/components/panda_cms/admin/user_display_component.html.erb +11 -0
- data/app/components/panda_cms/admin/user_display_component.rb +19 -0
- data/app/components/panda_cms/grid_component.html.erb +6 -0
- data/app/components/panda_cms/grid_component.rb +13 -0
- data/app/components/panda_cms/menu_component.html.erb +3 -0
- data/app/components/panda_cms/menu_component.rb +18 -0
- data/app/components/panda_cms/page_menu_component.html.erb +24 -0
- data/app/components/panda_cms/page_menu_component.rb +24 -0
- data/app/components/panda_cms/rich_text_component.html.erb +40 -0
- data/app/components/panda_cms/rich_text_component.rb +35 -0
- data/app/components/panda_cms/text_component.rb +67 -0
- data/app/constraints/panda_cms/admin_constraint.rb +16 -0
- data/app/controllers/panda_cms/admin/block_contents_controller.rb +44 -0
- data/app/controllers/panda_cms/admin/dashboard_controller.rb +31 -0
- data/app/controllers/panda_cms/admin/files_controller.rb +19 -0
- data/app/controllers/panda_cms/admin/forms_controller.rb +51 -0
- data/app/controllers/panda_cms/admin/menus_controller.rb +81 -0
- data/app/controllers/panda_cms/admin/pages_controller.rb +88 -0
- data/app/controllers/panda_cms/admin/posts_controller.rb +34 -0
- data/app/controllers/panda_cms/admin/sessions_controller.rb +83 -0
- data/app/controllers/panda_cms/admin/settings/bulk_editor_controller.rb +35 -0
- data/app/controllers/panda_cms/admin/settings_controller.rb +18 -0
- data/app/controllers/panda_cms/application_controller.rb +55 -0
- data/app/controllers/panda_cms/errors_controller.rb +31 -0
- data/app/controllers/panda_cms/form_submissions_controller.rb +21 -0
- data/app/controllers/panda_cms/pages_controller.rb +56 -0
- data/app/controllers/panda_cms/posts_controller.rb +17 -0
- data/app/helpers/panda_cms/admin/files_helper.rb +4 -0
- data/app/helpers/panda_cms/admin/pages_helper.rb +4 -0
- data/app/helpers/panda_cms/application_helper.rb +96 -0
- data/app/helpers/panda_cms/pages_helper.rb +4 -0
- data/app/helpers/panda_cms/theme_helper.rb +16 -0
- data/app/javascript/base.js +37 -0
- data/app/javascript/controllers/menu_controller.js +19 -0
- data/app/javascript/controllers/text_controller.js +78 -0
- data/app/javascript/controllers/text_field_update_controller.js +23 -0
- data/app/javascript/vendor/stimulus-components-rails-nested-form.js +2 -0
- data/app/javascript/vendor/tailwindcss-stimulus-components.js +2 -0
- data/app/jobs/panda_cms/application_job.rb +4 -0
- data/app/jobs/panda_cms/record_visit_job.rb +29 -0
- data/app/lib/panda_cms/bulk_editor.rb +169 -0
- data/app/lib/panda_cms/demo_site_generator.rb +70 -0
- data/app/lib/panda_cms/slug.rb +22 -0
- data/app/mailers/panda_cms/application_mailer.rb +6 -0
- data/app/mailers/panda_cms/form_mailer.rb +19 -0
- data/app/models/panda_cms/application_record.rb +5 -0
- data/app/models/panda_cms/block.rb +32 -0
- data/app/models/panda_cms/block_content.rb +16 -0
- data/app/models/panda_cms/block_content_version.rb +6 -0
- data/app/models/panda_cms/breadcrumb.rb +10 -0
- data/app/models/panda_cms/current.rb +15 -0
- data/app/models/panda_cms/form.rb +7 -0
- data/app/models/panda_cms/form_submission.rb +5 -0
- data/app/models/panda_cms/menu.rb +50 -0
- data/app/models/panda_cms/menu_item.rb +56 -0
- data/app/models/panda_cms/page.rb +81 -0
- data/app/models/panda_cms/page_version.rb +6 -0
- data/app/models/panda_cms/post.rb +25 -0
- data/app/models/panda_cms/post_version.rb +6 -0
- data/app/models/panda_cms/redirect.rb +9 -0
- data/app/models/panda_cms/template.rb +117 -0
- data/app/models/panda_cms/template_version.rb +6 -0
- data/app/models/panda_cms/user.rb +15 -0
- data/app/models/panda_cms/version.rb +6 -0
- data/app/models/panda_cms/visit.rb +7 -0
- data/app/views/layouts/panda_cms/application.html.erb +44 -0
- data/app/views/layouts/panda_cms/public.html.erb +3 -0
- data/app/views/panda_cms/admin/dashboard/show.html.erb +11 -0
- data/app/views/panda_cms/admin/files/index.html.erb +124 -0
- data/app/views/panda_cms/admin/files/show.html.erb +2 -0
- data/app/views/panda_cms/admin/forms/edit.html.erb +0 -0
- data/app/views/panda_cms/admin/forms/index.html.erb +13 -0
- data/app/views/panda_cms/admin/forms/new.html.erb +16 -0
- data/app/views/panda_cms/admin/forms/show.html.erb +35 -0
- data/app/views/panda_cms/admin/menus/_form.html.erb +21 -0
- data/app/views/panda_cms/admin/menus/_menu_item_fields.html.erb +7 -0
- data/app/views/panda_cms/admin/menus/edit.html.erb +58 -0
- data/app/views/panda_cms/admin/menus/index.html.erb +10 -0
- data/app/views/panda_cms/admin/menus/new.html.erb +5 -0
- data/app/views/panda_cms/admin/pages/edit.html.erb +26 -0
- data/app/views/panda_cms/admin/pages/index.html.erb +16 -0
- data/app/views/panda_cms/admin/pages/new.html.erb +16 -0
- data/app/views/panda_cms/admin/pages/show.html.erb +1 -0
- data/app/views/panda_cms/admin/posts/index.html.erb +16 -0
- data/app/views/panda_cms/admin/sessions/new.html.erb +18 -0
- data/app/views/panda_cms/admin/settings/bulk_editor/new.html.erb +68 -0
- data/app/views/panda_cms/admin/settings/index.html.erb +19 -0
- data/app/views/panda_cms/admin/shared/_breadcrumbs.html.erb +28 -0
- data/app/views/panda_cms/admin/shared/_flash.html.erb +5 -0
- data/app/views/panda_cms/admin/shared/_sidebar.html.erb +45 -0
- data/app/views/panda_cms/form_mailer/notification_email.html.erb +11 -0
- data/app/views/panda_cms/shared/_favicons.html.erb +9 -0
- data/app/views/panda_cms/shared/_footer.html.erb +2 -0
- data/app/views/panda_cms/shared/_header.html.erb +15 -0
- data/config/importmap.rb +9 -0
- data/config/initializers/panda_cms/form_errors.rb +38 -0
- data/config/initializers/panda_cms/healthcheck_log_silencer.rb +11 -0
- data/config/initializers/panda_cms.rb +52 -0
- data/config/locales/en.yml +29 -0
- data/config/routes.rb +43 -0
- data/config/tailwind.config.js +35 -0
- data/config/tailwind.embed.config.js +20 -0
- data/db/migrate/20240205223709_create_panda_cms_pages.rb +9 -0
- data/db/migrate/20240219213327_create_panda_cms_page_versions.rb +14 -0
- data/db/migrate/20240303002805_create_panda_cms_templates.rb +11 -0
- data/db/migrate/20240303003434_create_panda_cms_template_versions.rb +14 -0
- data/db/migrate/20240303022441_create_panda_cms_blocks.rb +13 -0
- data/db/migrate/20240303024256_create_panda_cms_block_contents.rb +10 -0
- data/db/migrate/20240303024746_create_panda_cms_block_content_versions.rb +14 -0
- data/db/migrate/20240303233238_add_panda_cms_menu_table.rb +10 -0
- data/db/migrate/20240303234724_add_panda_cms_menu_item_table.rb +12 -0
- data/db/migrate/20240304134343_add_parent_id_to_panda_cms_pages.rb +5 -0
- data/db/migrate/20240315125421_add_nested_sets_to_panda_cms_pages.rb +16 -0
- data/db/migrate/20240316212822_add_kind_to_panda_cms_menus.rb +6 -0
- data/db/migrate/20240316221425_add_start_page_to_panda_cms_menus.rb +5 -0
- data/db/migrate/20240316230706_add_nested_to_panda_cms_menu_items.rb +24 -0
- data/db/migrate/20240317010532_create_panda_cms_users.rb +12 -0
- data/db/migrate/20240317161534_add_max_uses_to_panda_cms_template.rb +7 -0
- data/db/migrate/20240317163053_reset_counter_cache_on_panda_cms_template.rb +5 -0
- data/db/migrate/20240317214827_create_panda_cms_redirects.rb +14 -0
- data/db/migrate/20240317230622_create_panda_cms_visits.rb +13 -0
- data/db/migrate/20240324205703_create_active_storage_tables.active_storage.rb +58 -0
- data/db/migrate/20240408084718_default_panda_cms_users_admin_to_false.rb +5 -0
- data/db/migrate/20240701225422_add_service_name_to_active_storage_blobs.active_storage.rb +22 -0
- data/db/migrate/20240701225423_create_active_storage_variant_records.active_storage.rb +28 -0
- data/db/migrate/20240701225424_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb +8 -0
- data/db/migrate/20240804110225_add_status_to_panda_cms_pages.rb +7 -0
- data/db/migrate/20240804235210_create_panda_cms_forms.rb +11 -0
- data/db/migrate/20240805013612_create_panda_cms_form_submissions.rb +9 -0
- data/db/migrate/20240805121123_create_panda_cms_posts.rb +27 -0
- data/db/migrate/20240805123104_create_panda_cms_post_versions.rb +14 -0
- data/db/migrate/20240806112735_fix_panda_cms_visits_column_names.rb +13 -0
- data/db/migrate/20240806204412_add_completion_path_to_panda_cms_forms.rb +5 -0
- data/db/migrate/20240820081917_change_form_submissions_to_submission_count.rb +5 -0
- data/db/seeds.rb +4 -0
- data/lib/generators/panda_cms/install_generator.rb +24 -0
- data/lib/panda_cms/engine.rb +167 -0
- data/lib/panda_cms/exceptions_app.rb +24 -0
- data/lib/panda_cms/version.rb +3 -0
- data/lib/panda_cms.rb +15 -0
- data/lib/tasks/panda_cms.rake +92 -0
- data/lib/templates/erb/scaffold/_form.html.erb.tt +43 -0
- data/lib/templates/erb/scaffold/edit.html.erb.tt +8 -0
- data/lib/templates/erb/scaffold/index.html.erb.tt +14 -0
- data/lib/templates/erb/scaffold/new.html.erb.tt +7 -0
- data/lib/templates/erb/scaffold/partial.html.erb.tt +22 -0
- data/lib/templates/erb/scaffold/show.html.erb.tt +15 -0
- data/public/panda-cms-assets/favicons/android-chrome-192x192.png +0 -0
- data/public/panda-cms-assets/favicons/android-chrome-512x512.png +0 -0
- data/public/panda-cms-assets/favicons/apple-touch-icon.png +0 -0
- data/public/panda-cms-assets/favicons/browserconfig.xml +9 -0
- data/public/panda-cms-assets/favicons/favicon-16x16.png +0 -0
- data/public/panda-cms-assets/favicons/favicon-32x32.png +0 -0
- data/public/panda-cms-assets/favicons/favicon.ico +0 -0
- data/public/panda-cms-assets/favicons/mstile-150x150.png +0 -0
- data/public/panda-cms-assets/favicons/safari-pinned-tab.svg +61 -0
- data/public/panda-cms-assets/favicons/site.webmanifest +14 -0
- data/public/panda-cms-assets/javascripts/base.js +37 -0
- data/public/panda-cms-assets/javascripts/controllers/menu_controller.js +19 -0
- data/public/panda-cms-assets/javascripts/controllers/text_field_update_controller.js +23 -0
- data/public/panda-cms-assets/javascripts/embed/editable.js +308 -0
- data/public/panda-cms-assets/javascripts/vendor/stimulus-components-rails-nested-form.js +2 -0
- data/public/panda-cms-assets/javascripts/vendor/stimulus-loading.js +113 -0
- data/public/panda-cms-assets/javascripts/vendor/tailwindcss-stimulus-components.js +2 -0
- data/public/panda-cms-assets/panda-logo-screenprint.png +0 -0
- data/public/panda-cms-assets/panda-nav.png +0 -0
- metadata +1034 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
<%= render PandaCms::Admin::ContainerComponent.new do |component| %>
|
2
|
+
<% component.with_heading(text: "Edit Menu", level: 1) %>
|
3
|
+
|
4
|
+
<%= panda_cms_form_with model: @menu, url: admin_menu_path, method: :put do |form| %>
|
5
|
+
<%= form.text_field :name %>
|
6
|
+
|
7
|
+
<% if @menu.kind == "static" %>
|
8
|
+
<div data-controller="nested-form" data-nested-form-wrapper-selector-value=".nested-form-wrapper">
|
9
|
+
<template data-nested-form-target="template">
|
10
|
+
<%= form.fields_for :menu_items, PandaCms::MenuItem.new, child_index: "NEW_RECORD" do |item| %>
|
11
|
+
<%= render "menu_item_fields", form: item %>
|
12
|
+
<% end %>
|
13
|
+
</template>
|
14
|
+
|
15
|
+
<% if @menu.menu_items.count > 0 %>
|
16
|
+
<%= form.fields_for :menu_items, @menu.menu_items.sort_by(&:lft) do |item| %>
|
17
|
+
<%= render "menu_item_fields", form: item %>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
20
|
+
|
21
|
+
<div data-nested-form-target="target"></div>
|
22
|
+
|
23
|
+
<%= render PandaCms::Admin::ButtonComponent.new(text: "Add Menu Item", action: :add, data: {action: "nested-form#add"}, size: :small) %>
|
24
|
+
</div>
|
25
|
+
<% else %>
|
26
|
+
<table class="-mx-3 min-w-full divide-y divide-gray-300">
|
27
|
+
<thead>
|
28
|
+
<tr>
|
29
|
+
<th scope="col" class="py-3.5 px-3 text-sm font-semibold text-left text-gray-900">Text</th>
|
30
|
+
<th scope="col" class="py-3.5 px-3 text-sm font-semibold text-left text-gray-900">Page</th>
|
31
|
+
<th scope="col" class="py-3.5 px-3 text-sm font-semibold text-left text-gray-900">External Link</th>
|
32
|
+
</tr>
|
33
|
+
</thead>
|
34
|
+
<tbody class="bg-white divide-y divide-gray-200">
|
35
|
+
<% @menu.menu_items.root.self_and_descendants.each do |menu_item| %>
|
36
|
+
<tr>
|
37
|
+
<td class="py-5 pr-3 pl-3 text-sm whitespace-nowrap">
|
38
|
+
<div class="flex items-center">
|
39
|
+
<div class="<%= table_indent(menu_item) %>">
|
40
|
+
<div class="font-medium text-gray-900"><%= menu_item.text %></div>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
</td>
|
44
|
+
<td class="py-5 px-3 text-sm text-gray-500 whitespace-nowrap">
|
45
|
+
<div class="text-gray-900"><%= menu_item.page.title %></div>
|
46
|
+
</td>
|
47
|
+
<td class="py-5 px-3 text-sm text-gray-500 whitespace-nowrap">
|
48
|
+
<div class="text-gray-900"><%= menu_item.external_url %></div>
|
49
|
+
</td>
|
50
|
+
</tr>
|
51
|
+
<% end %>
|
52
|
+
</tbody>
|
53
|
+
</table>
|
54
|
+
<% end %>
|
55
|
+
|
56
|
+
<%= form.button %>
|
57
|
+
<% end %>
|
58
|
+
<% end %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= render PandaCms::Admin::ContainerComponent.new do |component| %>
|
2
|
+
<% component.with_heading(text: "Menus", level: 1) do |heading| %>
|
3
|
+
<% heading.with_button(action: :add, text: "Add Menu", link: new_admin_menu_path) %>
|
4
|
+
<% end %>
|
5
|
+
|
6
|
+
<%= render PandaCms::Admin::TableComponent.new(rows: menus) do |table| %>
|
7
|
+
<% table.column("Name") { |menu| link_to menu.name, edit_admin_menu_path(menu) } %>
|
8
|
+
<% table.column("Kind") { |menu| render PandaCms::Admin::TagComponent.new(status: :active, text: menu.kind.titleize) } %>
|
9
|
+
<% end %>
|
10
|
+
<% end %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<%= render PandaCms::Admin::ContainerComponent.new do |component| %>
|
2
|
+
<% component.with_heading(text: "#{page.title}", level: 1) %>
|
3
|
+
|
4
|
+
<% component.with_slideover(title: "Page Details") do %>
|
5
|
+
<%= panda_cms_form_with model: page, url: admin_page_path, method: :put do |f| %>
|
6
|
+
<%= f.text_field :title, class: "block w-full rounded-md border-0 p-2 text-gray-900 ring-1 ring-inset ring-mid placeholder:text-gray-300 focus:ring-1 focus:ring-inset focus:ring-dark sm:text-sm sm:leading-6 hover:pointer" %>
|
7
|
+
|
8
|
+
<%= f.text_field :template, value: template.name, readonly: true, class: "read-only:bg-gray-100 block w-full rounded-md border-0 p-2 text-gray-900 ring-1 ring-inset ring-mid placeholder:text-gray-300 focus:ring-1 focus:ring-inset focus:ring-dark sm:text-sm sm:leading-6 hover:pointer" %>
|
9
|
+
|
10
|
+
<%= f.select :status, options_for_select([["Active", "active"], ["Draft", "draft"], ["Hidden", "hidden"], ["Archived", "archived"]], selected: page.status), {}, class: "block w-full rounded-md border-0 py-1.5 pl-3 pr-10 text-gray-900 ring-1 ring-inset ring-mid focus:ring-1 focus:ring-inset focus:ring-dark sm:text-sm sm:leading-6 hover:pointer" %>
|
11
|
+
|
12
|
+
<%= f.submit "Save" %>
|
13
|
+
<% end %>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<a class="block mb-2 -mt-4 text-sm text-black/60" target="_blank" href="<%= @page.path %>"><%= @page.path %> <i class="ml-2 fa-solid fa-arrow-up-right-from-square"></i></a>
|
17
|
+
|
18
|
+
<iframe id="editablePageFrame" src="<%= page.path %>?embed_id=<%= page.id %>" class="p-0 m-0 w-full h-full border border-slate-200"></iframe>
|
19
|
+
|
20
|
+
<script src="/panda-cms-assets/javascripts/embed/editable.js"></script>
|
21
|
+
<script>
|
22
|
+
document.addEventListener("DOMContentLoaded", function() {
|
23
|
+
const editable = new EditableController("<%= page.id %>", document.getElementById("editablePageFrame"));
|
24
|
+
});
|
25
|
+
</script>
|
26
|
+
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<%= render PandaCms::Admin::ContainerComponent.new do |component| %>
|
2
|
+
<% component.with_heading(text: "Pages", level: 1) do |heading| %>
|
3
|
+
<% heading.with_button(action: :add, text: "Add Page", link: new_admin_page_path) %>
|
4
|
+
<% end %>
|
5
|
+
|
6
|
+
<%= render PandaCms::Admin::TableComponent.new(rows: root_page.self_and_descendants) do |table| %>
|
7
|
+
<% table.column("Name") do |page| %>
|
8
|
+
<div class="<%= table_indent(page) %>">
|
9
|
+
<%= link_to page.title, edit_admin_page_path(page), class: "block h-full w-full" %>
|
10
|
+
<span class="block text-xs text-black/60"><%= page.path %></span>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
<% table.column("Status") { |page| render PandaCms::Admin::TagComponent.new(status: page.status) } %>
|
14
|
+
<% table.column("Last Updated") { |page| render PandaCms::Admin::UserActivityComponent.new(whodunnit_to: page)} %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<%= render PandaCms::Admin::ContainerComponent.new do |component| %>
|
2
|
+
<% component.with_heading(text: "Add Page", level: 1) do |heading| %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<%= panda_cms_form_with model: page, url: admin_pages_path, method: :post do |f| %>
|
6
|
+
<% options = nested_set_options(PandaCms::Page, page) { |i| "#{"-" * i.level} #{i.title} (#{i.path})" } %>
|
7
|
+
<div data-controller="text-field-update">
|
8
|
+
<input type="hidden" value="<%= PandaCms::Current.root %>" data-text-field-update-target="existing_root">
|
9
|
+
<%= f.select :parent_id, options, {}, { "data-text-field-update-target": "input_select", "data-action": "change->text-field-update#setPrePath" } %>
|
10
|
+
<%= f.text_field :title, { data: { "text-field-update-target": "input_text", action: "focusout->text-field-update#generatePath" } } %>
|
11
|
+
<%= f.text_field :path, { data: { prefix: PandaCms::Current.root, "text-field-update-target": "output_text" } } %>
|
12
|
+
<%= f.collection_select :panda_cms_template_id, PandaCms::Template.available, :id, :name %>
|
13
|
+
<%= f.button %>
|
14
|
+
</div>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
Show page
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<%= render PandaCms::Admin::ContainerComponent.new do |component| %>
|
2
|
+
<% component.with_heading(text: "Posts", level: 1) do |heading| %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<%= render PandaCms::Admin::TableComponent.new(rows: posts) do |table| %>
|
6
|
+
<% table.column("Title") do |post| %>
|
7
|
+
<div class="">
|
8
|
+
<%= link_to post.title, edit_admin_post_path(post), class: "block h-full w-full" %>
|
9
|
+
<span class="block text-xs text-black/60"><%= post.path %></span>
|
10
|
+
</div>
|
11
|
+
<% end %>
|
12
|
+
<% table.column("Status") { |post| render PandaCms::Admin::TagComponent.new(status: post.status) } %>
|
13
|
+
<% table.column("Last Updated") { |post| render PandaCms::Admin::UserActivityComponent.new(whodunnit_to: post)} %>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<% end %>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<div class="flex flex-col justify-center py-12 px-6 min-h-full text-center lg:px-8">
|
2
|
+
<div class="text-center sm:mx-auto sm:w-full sm:max-w-sm">
|
3
|
+
<img src="/panda-cms-assets/panda-nav.png" class="py-2 mx-auto w-auto h-32">
|
4
|
+
<h2 class="mt-10 mb-6 text-2xl font-bold text-center text-white"><%= t("panda_cms.admin.sessions.new.title") %></h2>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<% @providers.each do |provider| %>
|
8
|
+
<div class="mt-4 text-center sm:mx-auto sm:w-full sm:max-w-sm">
|
9
|
+
<%= form_tag "#{PandaCms.admin_path}/auth/#{provider}", method: "post", data: {turbo: false} do %>
|
10
|
+
<input type="hidden" name="redirect_uri" value="<%= admin_login_callback_url(provider: provider) %>">
|
11
|
+
<button type="submit" id="button-sign-in-<%= provider %>" class="inline-flex gap-x-2 items-center py-2.5 px-3.5 mx-auto mb-4 bg-white rounded-md border min-w-56 border-neutral-400">
|
12
|
+
<i class="fa-brands fa-<%= provider %> text-xl mr-1"></i>
|
13
|
+
<%= t("panda_cms.authentication.sign_in_with", provider: t("panda_cms.authentication.providers.#{provider}")) %>
|
14
|
+
</button>
|
15
|
+
<% end %>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
18
|
+
</div>
|
@@ -0,0 +1,68 @@
|
|
1
|
+
<%= render PandaCms::Admin::ContainerComponent.new do |component| %>
|
2
|
+
<% component.with_heading(text: "Bulk Editor", level: 1) %>
|
3
|
+
|
4
|
+
<% if @debug && @debug[:error].any? %>
|
5
|
+
<div class="p-4 mb-4 bg-red-50 rounded-md">
|
6
|
+
<div class="flex">
|
7
|
+
<div class="flex-shrink-0">
|
8
|
+
<i class="text-xl text-red-600 fa-sharp-duotone fa-solid fa-circle-exclamation"></i>
|
9
|
+
</div>
|
10
|
+
<div class="ml-3">
|
11
|
+
<h3 class="text-base font-medium text-red-700">Errors:</h3>
|
12
|
+
<div class="mt-2 text-sm text-red-700">
|
13
|
+
<ul role="list" class="pl-5 list-disc">
|
14
|
+
<% @debug[:error].each do |error| %>
|
15
|
+
<li><%= error %></li>
|
16
|
+
<% end %>
|
17
|
+
</ul>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<% if @debug && @debug[:warning].any? %>
|
25
|
+
<div class="p-4 mb-4 bg-yellow-50 rounded-md">
|
26
|
+
<div class="flex">
|
27
|
+
<div class="flex-shrink-0">
|
28
|
+
<i class="text-xl text-yellow-600 fa-duotone fa-solid fa-triangle-exclamation"></i>
|
29
|
+
</div>
|
30
|
+
<div class="ml-3">
|
31
|
+
<h3 class="text-base font-medium text-yellow-700">Warnings:</h3>
|
32
|
+
<div class="mt-2 text-sm text-yellow-700">
|
33
|
+
<ul role="list" class="pl-5 list-disc">
|
34
|
+
<% @debug[:warning].each do |warning| %>
|
35
|
+
<li><%= warning %></li>
|
36
|
+
<% end %>
|
37
|
+
</ul>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
</div>
|
42
|
+
<% end %>
|
43
|
+
|
44
|
+
<% if @debug && @debug[:success].any? %>
|
45
|
+
<div class="p-4 mb-4 bg-green-50 rounded-md">
|
46
|
+
<div class="flex">
|
47
|
+
<div class="flex-shrink-0">
|
48
|
+
<i class="text-xl text-green-600 fa-duotone fa-solid fa-circle-check"></i>
|
49
|
+
</div>
|
50
|
+
<div class="ml-3">
|
51
|
+
<h3 class="text-base font-medium text-green-700">Updates:</h3>
|
52
|
+
<div class="mt-2 text-sm text-green-700">
|
53
|
+
<ul role="list" class="pl-5 list-disc">
|
54
|
+
<% @debug[:success].each do |success| %>
|
55
|
+
<li><%= success %></li>
|
56
|
+
<% end %>
|
57
|
+
</ul>
|
58
|
+
</div>
|
59
|
+
</div>
|
60
|
+
</div>
|
61
|
+
</div>
|
62
|
+
<% end %>
|
63
|
+
|
64
|
+
<%= panda_cms_form_with method: :post do |form| %>
|
65
|
+
<%= form.text_area :site_content, value: @json_data, cols: 70, rows: 10, class: "block font-mono w-full" %>
|
66
|
+
<%= form.button "Update" %>
|
67
|
+
<% end %>
|
68
|
+
<% end %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<%= render PandaCms::Admin::ContainerComponent.new do |component| %>
|
2
|
+
<% component.with_heading(text: "Settings", level: 1) %>
|
3
|
+
|
4
|
+
<a href="https://api.instagram.com/oauth/authorize?client_id=1149927569456763&redirect_uri=http://localhost:3000/admin/integrations/instagram/callback&scope=user_profile,user_media">Login to Instagram</a>
|
5
|
+
|
6
|
+
<%= render PandaCms::Admin::PanelComponent.new do |panel| %>
|
7
|
+
<% panel.with_heading(text: "System Status") %>
|
8
|
+
|
9
|
+
<p class="text-base leading-loose"><i class="mr-2 text-active fa fa-check-circle"></i> <span class="font-medium">Panda CMS:</span> v<%= PandaCms::VERSION %></p>
|
10
|
+
<p class="text-base leading-loose"><i class="mr-2 text-active fa fa-check-circle"></i> <span class="font-medium">Rails:</span> v<%= Rails.version %></p>
|
11
|
+
<p class="text-base leading-loose"><i class="mr-2 text-active fa fa-check-circle"></i> <span class="font-medium">Ruby:</span> v<%= RUBY_VERSION %></p>
|
12
|
+
<p class="text-base leading-loose"><i class="mr-2 text-active fa fa-check-circle"></i> <span class="font-medium">Environment:</span> <%= Rails.env.titleize %></p>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<div class="text-center mt-6 space-y-2">
|
16
|
+
<p class="text-sm font-semibold">🐼 Panda CMS version: <%= PandaCms::VERSION %></p>
|
17
|
+
<p class="text-sm">© <%= Date.current.year %> Panda Software Limited. All rights reserved.</p>
|
18
|
+
</div>
|
19
|
+
<% end %>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<% breadcrumb_styles = "text-black/60 hover:text-black/80" %>
|
2
|
+
|
3
|
+
<div class="flex mt-1 -mb-1">
|
4
|
+
<nav aria-label="Breadcrumb" id="panda-breadcrumbs" class="grow">
|
5
|
+
<ol role="list" class="px-4 w-full sm:px-6">
|
6
|
+
<li class="inline-block">
|
7
|
+
<a href="/admin" class="<%= breadcrumb_styles %>">
|
8
|
+
<i class="fa fa-regular fa-house"></i>
|
9
|
+
<span class="sr-only">Home</span>
|
10
|
+
</a>
|
11
|
+
</li>
|
12
|
+
<% breadcrumbs.each do |crumb| %>
|
13
|
+
<li class="inline-block">
|
14
|
+
<i class="fa fa-regular fa-chevron-right font-light <%= breadcrumb_styles %> py-5 px-2"></i>
|
15
|
+
<a href="<%= crumb.path %>" class="text-sm font-normal <%= breadcrumb_styles %>"><%= crumb.name %></a>
|
16
|
+
</li>
|
17
|
+
<% end %>
|
18
|
+
</ol>
|
19
|
+
</nav>
|
20
|
+
|
21
|
+
<% if content_for :sidebar %>
|
22
|
+
<div class="pt-4 pr-8 text-black/80" tabindex="-1">
|
23
|
+
<a href="#" id="slideover-toggle" data-action="click->toggle#toggle touch->toggle#toggle" class="text-sm font-light">
|
24
|
+
<i class="mr-1 fa-light fa-gear"></i> <%= yield :sidebar_title %>
|
25
|
+
</a>
|
26
|
+
</div>
|
27
|
+
<% end %>
|
28
|
+
</div>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<nav class="flex flex-col flex-1">
|
2
|
+
<ul role="list" class="flex flex-col flex-1">
|
3
|
+
<a class="block p-0 mt-4 mb-4 ml-2 text-xl font-medium text-white"><%= PandaCms.title %></a>
|
4
|
+
|
5
|
+
<% [
|
6
|
+
{ path: admin_dashboard_path, text: "Dashboard", icon: "fa-house", matcher: :exact },
|
7
|
+
{ path: admin_pages_path, text: "Pages", icon: "fa-page", matcher: :starts_with },
|
8
|
+
{ path: admin_posts_path, text: "Posts", icon: "fa-notebook", matcher: :starts_with },
|
9
|
+
{ path: admin_forms_path, text: "Forms", icon: "fa-cabinet-filing", matcher: :starts_with },
|
10
|
+
{ path: admin_menus_path, text: "Menus", icon: "fa-list-dropdown", matcher: :starts_with },
|
11
|
+
{ path: admin_settings_path, text: "Settings", icon: "fa-cog", matcher: :starts_with },
|
12
|
+
].each do |link| %>
|
13
|
+
<li>
|
14
|
+
<%= link_to link[:path], class: "#{active_link?(link[:path], match: link[:matcher]) ? selected_nav_highlight_colour_classes(request) : nav_highlight_colour_classes(request)}" do %>
|
15
|
+
<span class="text-center"><i class="fa-regular <%= link[:icon] %> text-xl fa-fw"></i></span>
|
16
|
+
<span class="mt-1"><%= link[:text] %></span>
|
17
|
+
<% end %>
|
18
|
+
</li>
|
19
|
+
<% end %>
|
20
|
+
<li>
|
21
|
+
<%= button_to admin_logout_path, method: :delete, data: { turbo: false }, class: nav_highlight_colour_classes(request) + " w-full" do %>
|
22
|
+
<span class="text-center"><i class="text-xl fa-regular fa-door-open fa-fw"></i></span>
|
23
|
+
<span class="mt-1">Sign Out</span>
|
24
|
+
<% end %>
|
25
|
+
</li>
|
26
|
+
|
27
|
+
<li class="mt-auto">
|
28
|
+
<%= button_to '#', data: { turbo: false }, class: nav_highlight_colour_classes(request) + " w-full" do %>
|
29
|
+
<% if !current_user.image_url.empty? %>
|
30
|
+
<span class="text-center"><img src="<%= current_user.image_url %>" class="w-auto h-7 rounded-full"></span>
|
31
|
+
<% else %>
|
32
|
+
<span class="text-center"><i class="text-xl fa-regular fa-circle-user fa-fw"></i></span>
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
<span class="mt-0.5"><%= current_user.firstname %> <%= current_user.lastname %></span>
|
36
|
+
<% end %>
|
37
|
+
</li>
|
38
|
+
|
39
|
+
<li class="">
|
40
|
+
<img src="/panda-cms-assets/panda-nav.png" class="inline py-2 mr-1 ml-0.5 w-auto h-14">
|
41
|
+
<span class="text-xs text-white">v<%= PandaCms::VERSION %> | <span class="font-semibold">License:</span> Perpetual</span>
|
42
|
+
<a class="absolute right-0 mt-4 mr-5 text-lg text-white lg:hidden" href="#" data-action="click->panda-cms-menu#toggle touch->panda-cms-menu#toggle"><i class="mr-2 text-white fa-sharp fa-solid fa-bars"></i> Menu</a>
|
43
|
+
</li>
|
44
|
+
</ul>
|
45
|
+
</nav>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<link rel="apple-touch-icon" sizes="180x180" href="/panda-cms-assets/favicons/apple-touch-icon.png">
|
2
|
+
<link rel="icon" type="image/png" sizes="32x32" href="/panda-cms-assets/favicons/favicon-32x32.png">
|
3
|
+
<link rel="icon" type="image/png" sizes="16x16" href="/panda-cms-assets/favicons/favicon-16x16.png">
|
4
|
+
<link rel="manifest" href="/panda-cms-assets/favicons/site.webmanifest">
|
5
|
+
<link rel="mask-icon" href="/panda-cms-assets/favicons/safari-pinned-tab.svg" color="#5bbad5">
|
6
|
+
<link rel="shortcut icon" href="/panda-cms-assets/favicons/favicon.ico">
|
7
|
+
<meta name="msapplication-TileColor" content="#b91d47">
|
8
|
+
<meta name="msapplication-config" content="/panda-cms-assets/favicons/browserconfig.xml">
|
9
|
+
<meta name="theme-color" content="#ffffff">
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html data-theme="default" class="<%= html_class ||= "" %>">
|
3
|
+
<head>
|
4
|
+
<title>Panda CMS</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
<script src="https://kit.fontawesome.com/7835d81e75.js" crossorigin="anonymous"></script>
|
8
|
+
<script async src="https://ga.jspm.io/npm:es-module-shims@1.10.0/dist/es-module-shims.js" crossorigin="anonymous"></script>
|
9
|
+
<%= stylesheet_link_tag "panda_cms", "data-turbo-track": "reload" %>
|
10
|
+
<%= javascript_importmap_tags "panda_cms/base" %>
|
11
|
+
<%= render "panda_cms/shared/favicons" %>
|
12
|
+
</head>
|
13
|
+
|
14
|
+
<body class="overflow-hidden h-full">
|
15
|
+
<%= render "panda_cms/admin/shared/flash" %>
|
data/config/importmap.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
pin "@hotwired/stimulus", to: "https://ga.jspm.io/npm:stimulus@3.2.2/dist/stimulus.js"
|
2
|
+
pin "@hotwired/stimulus-loading", to: "/panda-cms-assets/javascripts/vendor/stimulus-loading.js" # 3.2.2
|
3
|
+
|
4
|
+
pin "panda_cms/vendor/stimulus-components-rails-nested-form", to: "/panda-cms-assets/javascripts/vendor/stimulus-components-rails-nested-form.js", preload: false
|
5
|
+
pin "panda_cms/vendor/tailwindcss-stimulus-components", to: "/panda-cms-assets/javascripts/vendor/tailwindcss-stimulus-components.js", preload: false
|
6
|
+
pin "panda_cms/controllers/menu_controller", to: "/panda-cms-assets/javascripts/controllers/menu_controller.js", preload: false
|
7
|
+
pin "panda_cms/controllers/text_field_update_controller", to: "/panda-cms-assets/javascripts/controllers/text_field_update_controller.js", preload: false
|
8
|
+
pin "panda_cms/embed/editable", to: "/panda-cms-assets/javascripts/embed/editable.js", preload: false
|
9
|
+
pin "panda_cms/base", to: "/panda-cms-assets/javascripts/base.js", preload: false
|
@@ -0,0 +1,38 @@
|
|
1
|
+
ActionView::Base.field_error_proc = proc do |html_tag, instance|
|
2
|
+
html = ""
|
3
|
+
form_fields = %w[input select textarea trix-editor label].join(", ")
|
4
|
+
error_class = "text-red-600 dark:text-red-500 bg-red-50 border-red-500 border-1 box-shadow-red-500 focus:ring-red-500 focus:border-red-500 dark:bg-red-900 dark:border-red-500 dark:focus:ring-red-500 dark:focus:border-red-500"
|
5
|
+
message_class = "block w-full text-sm font-bold p-0 m-0 mt-1 text-red-700"
|
6
|
+
autofocused = false
|
7
|
+
|
8
|
+
Nokogiri::HTML::DocumentFragment.parse(html_tag).css(form_fields).each do |element|
|
9
|
+
if form_fields.include?(element.node_name)
|
10
|
+
if !autofocused
|
11
|
+
# element.attribute("autofocus", "true")
|
12
|
+
autofocused = true
|
13
|
+
end
|
14
|
+
|
15
|
+
message = "#{instance.object.class.human_attribute_name(instance.send(:sanitized_method_name))} "
|
16
|
+
message += if instance.error_message.respond_to?(:each)
|
17
|
+
"#{instance.error_message.uniq.to_sentence}."
|
18
|
+
else
|
19
|
+
"#{instance.error_message}."
|
20
|
+
end
|
21
|
+
|
22
|
+
if element.node_name.eql?("label")
|
23
|
+
html = element.to_s
|
24
|
+
else
|
25
|
+
element.add_class(error_class)
|
26
|
+
html = if element.get_attribute("data-prefix")
|
27
|
+
"#{element}</div><div class=\"#{message_class}\">#{message}"
|
28
|
+
elsif element.get_attribute("type") != "checkbox"
|
29
|
+
"#{element}<div class=\"#{message_class}\">#{message}</div>"
|
30
|
+
else
|
31
|
+
element.to_s
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
html.html_safe
|
38
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Base URL
|
2
|
+
PandaCms.url = "http://localhost:3000"
|
3
|
+
# The main title of your website
|
4
|
+
# The default is "Demo Site"
|
5
|
+
PandaCms.title = "Demo Site"
|
6
|
+
# The path to the administration panel, which must start with a /
|
7
|
+
# The default is "/admin"
|
8
|
+
PandaCms.admin_path = "/admin"
|
9
|
+
# Is login required to access the site?
|
10
|
+
PandaCms.require_login_to_view = false
|
11
|
+
# Authentication providers
|
12
|
+
PandaCms.authentication = {
|
13
|
+
microsoft: {
|
14
|
+
enabled: false,
|
15
|
+
# Setup at the following URL:
|
16
|
+
# https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade
|
17
|
+
client_id: Rails.application.credentials.dig(:microsoft, :client_id),
|
18
|
+
client_secret: Rails.application.credentials.dig(:microsoft, :client_secret),
|
19
|
+
# Don't change this or the sky will fall on your head
|
20
|
+
# https://github.com/synth/omniauth-microsoft_graph/tree/main?tab=readme-ov-file#domain-verification
|
21
|
+
skip_domain_verification: false,
|
22
|
+
# If your application is single-tenanted, replace "common" with your tenant (directory) ID
|
23
|
+
# from https://portal.azure.com/#settings/directory, otherwise you'll likely want to leave
|
24
|
+
# these settings unchanged
|
25
|
+
client_options: {
|
26
|
+
site: "https://login.microsoftonline.com/",
|
27
|
+
token_url: "common/oauth2/v2.0/token",
|
28
|
+
authorize_url: "common/oauth2/v2.0/authorize"
|
29
|
+
},
|
30
|
+
# If you assign specific users or groups, you will likely want to set this to true to enable
|
31
|
+
# auto-provisioning
|
32
|
+
create_account_on_first_login: true,
|
33
|
+
redirect_uri: Rails.application.credentials.dig(:microsoft, :redirect_uri)
|
34
|
+
},
|
35
|
+
google: {
|
36
|
+
enabled: false,
|
37
|
+
create_account_on_first_login: true,
|
38
|
+
create_admin_account_on_first_login: false,
|
39
|
+
redirect_uri: Rails.application.credentials.dig(:google, :redirect_uri)
|
40
|
+
},
|
41
|
+
github: {
|
42
|
+
enabled: true,
|
43
|
+
create_account_on_first_login: true,
|
44
|
+
create_admin_account_on_first_login: false,
|
45
|
+
redirect_uri: Rails.application.credentials.dig(:github, :redirect_uri)
|
46
|
+
}
|
47
|
+
}
|
48
|
+
# Blog
|
49
|
+
PandaCms.posts = {
|
50
|
+
enabled: true,
|
51
|
+
prefix: "blog"
|
52
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
en:
|
2
|
+
activerecord:
|
3
|
+
attributes:
|
4
|
+
panda_cms/page:
|
5
|
+
title: Title
|
6
|
+
path: Path
|
7
|
+
panda_cms_template_id: Template
|
8
|
+
panda_cms/menu:
|
9
|
+
name: Menu Name
|
10
|
+
panda_cms/menu_item:
|
11
|
+
text: Menu Item
|
12
|
+
external_url: External URL
|
13
|
+
panda_cms_page_id: Page
|
14
|
+
panda_cms:
|
15
|
+
authentication:
|
16
|
+
sign_in_with: Sign in with %{provider}
|
17
|
+
providers:
|
18
|
+
github: GitHub
|
19
|
+
google: Google
|
20
|
+
microsoft: Microsoft 365
|
21
|
+
admin:
|
22
|
+
sessions:
|
23
|
+
create:
|
24
|
+
error: There was an error logging you in. Please check your login details and try again, or contact support.
|
25
|
+
success: You are logged in!
|
26
|
+
destroy:
|
27
|
+
success: You have been logged out!
|
28
|
+
new:
|
29
|
+
title: Sign in to your account
|
data/config/routes.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require_relative "../app/constraints/panda_cms/admin_constraint"
|
2
|
+
|
3
|
+
PandaCms::Engine.routes.draw do
|
4
|
+
constraints PandaCms::AdminConstraint.new(&:present?) do
|
5
|
+
namespace PandaCms.admin_path_symbol.to_sym, as: :admin, module: :admin do
|
6
|
+
resources :files
|
7
|
+
resources :forms, only: %i[index show]
|
8
|
+
resources :menus
|
9
|
+
resources :pages do
|
10
|
+
resources :block_contents, only: %i[update]
|
11
|
+
end
|
12
|
+
resources :posts
|
13
|
+
|
14
|
+
get "settings", to: "settings#index"
|
15
|
+
namespace :settings, as: :settings do
|
16
|
+
get "bulk_editor", to: "bulk_editor#new"
|
17
|
+
post "bulk_editor", to: "bulk_editor#create"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
get PandaCms.admin_path, to: "admin/dashboard#show", as: :admin_dashboard
|
22
|
+
end
|
23
|
+
|
24
|
+
### PUBLIC ROUTES ###
|
25
|
+
|
26
|
+
# Authentication routes
|
27
|
+
get PandaCms.admin_path, to: "admin/sessions#new", as: :admin_login
|
28
|
+
# Get and post options here are for OmniAuth coming back in, not going out
|
29
|
+
match "#{PandaCms.admin_path}/auth/:provider/callback", to: "admin/sessions#create", as: :admin_login_callback, via: %i[get post]
|
30
|
+
match "#{PandaCms.admin_path}/auth/failure", to: "admin/sessions#failure", as: :admin_login_failure, via: %i[get post]
|
31
|
+
# OmniAuth additionally adds a GET route for "#{PandaCms.admin_path}/auth/:provider" but doesn't name it
|
32
|
+
delete PandaCms.admin_path, to: "admin/sessions#destroy", as: :admin_logout
|
33
|
+
|
34
|
+
if PandaCms.posts
|
35
|
+
# TODO: Allow multiple types of post in future
|
36
|
+
get PandaCms.posts[:prefix], to: "posts#index", as: :posts
|
37
|
+
get "#{PandaCms.posts[:prefix]}/:slug", to: "posts#show", as: :post
|
38
|
+
end
|
39
|
+
|
40
|
+
### APPENDED ROUTES ###
|
41
|
+
|
42
|
+
# See lib/panda_cms/engine.rb
|
43
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module.exports = {
|
2
|
+
content: {
|
3
|
+
relative: true,
|
4
|
+
files: [
|
5
|
+
"../public/*.html",
|
6
|
+
"../app/views/**/*.html.erb",
|
7
|
+
"../app/components/panda_cms/**/*.html.erb",
|
8
|
+
"../app/components/panda_cms/**/*.rb",
|
9
|
+
"../app/helpers/panda_cms/**/*.rb",
|
10
|
+
"../app/javascript/panda_cms/**/*.js",
|
11
|
+
"../vendor/javascript/**/*.js",
|
12
|
+
],
|
13
|
+
},
|
14
|
+
theme: {
|
15
|
+
colors: {
|
16
|
+
transparent: "transparent",
|
17
|
+
current: "currentColor",
|
18
|
+
white: "rgb(var(--color-white) / <alpha-value>)",
|
19
|
+
black: "rgb(var(--color-black) / <alpha-value>)",
|
20
|
+
light: "rgb(var(--color-light) / <alpha-value>)",
|
21
|
+
mid: "rgb(var(--color-mid) / <alpha-value>)",
|
22
|
+
dark: "rgb(var(--color-dark) / <alpha-value>)",
|
23
|
+
highlight: "rgb(var(--color-highlight) / <alpha-value>)",
|
24
|
+
active: "rgb(var(--color-active) / <alpha-value>)",
|
25
|
+
warning: "rgb(var(--color-warning) / <alpha-value>)",
|
26
|
+
error: "rgb(var(--color-error) / <alpha-value>)",
|
27
|
+
},
|
28
|
+
},
|
29
|
+
plugins: [
|
30
|
+
require("@tailwindcss/forms"),
|
31
|
+
require("@tailwindcss/aspect-ratio"),
|
32
|
+
require("@tailwindcss/typography"),
|
33
|
+
require("@tailwindcss/container-queries"),
|
34
|
+
],
|
35
|
+
};
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module.exports = {
|
2
|
+
content: [
|
3
|
+
"./app/helpers/**/*.rb",
|
4
|
+
"./app/components/**/*.rb",
|
5
|
+
"./app/components/**/*.html.erb",
|
6
|
+
],
|
7
|
+
theme: {
|
8
|
+
extend: {
|
9
|
+
colors: {
|
10
|
+
panda: {
|
11
|
+
light: "#86a9db",
|
12
|
+
dark: "#404c5c",
|
13
|
+
alternate: "#ea565d"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
},
|
17
|
+
},
|
18
|
+
plugins: [],
|
19
|
+
prefix: "panda-cms-"
|
20
|
+
}
|