plum-cms 0.1.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 +7 -0
- data/CHANGELOG.md +20 -0
- data/LICENSE.txt +21 -0
- data/README.md +252 -0
- data/app/assets/builds/tailwind.css +2 -0
- data/app/assets/images/plum-mark.svg +7 -0
- data/app/assets/images/table-needs-logo.svg +83 -0
- data/app/assets/javascripts/plum/application.js +15 -0
- data/app/assets/stylesheets/application.css +10 -0
- data/app/assets/stylesheets/plum/control_panel.css +2 -0
- data/app/assets/tailwind/application.css +47 -0
- data/app/controllers/plum/application_controller.rb +34 -0
- data/app/controllers/plum/cp/assets_controller.rb +84 -0
- data/app/controllers/plum/cp/base_controller.rb +45 -0
- data/app/controllers/plum/cp/content_types_controller.rb +59 -0
- data/app/controllers/plum/cp/dashboard_controller.rb +10 -0
- data/app/controllers/plum/cp/entries_controller.rb +240 -0
- data/app/controllers/plum/cp/form_definitions_controller.rb +105 -0
- data/app/controllers/plum/cp/form_submissions_controller.rb +26 -0
- data/app/controllers/plum/cp/globals_controller.rb +84 -0
- data/app/controllers/plum/cp/nav_items_controller.rb +68 -0
- data/app/controllers/plum/cp/nav_menus_controller.rb +56 -0
- data/app/controllers/plum/cp/site_settings_controller.rb +87 -0
- data/app/controllers/plum/cp/taxonomies_controller.rb +56 -0
- data/app/controllers/plum/cp/terms_controller.rb +55 -0
- data/app/controllers/plum/cp/theme_previews_controller.rb +27 -0
- data/app/controllers/plum/cp/themes_controller.rb +98 -0
- data/app/controllers/plum/form_submissions_controller.rb +44 -0
- data/app/controllers/plum/pages_controller.rb +161 -0
- data/app/controllers/plum/sessions_controller.rb +25 -0
- data/app/controllers/plum/theme_assets_controller.rb +14 -0
- data/app/helpers/application_helper.rb +2 -0
- data/app/helpers/markdown_helper.rb +21 -0
- data/app/helpers/plum/cp/assets_helper.rb +21 -0
- data/app/helpers/plum/cp/theme_settings_helper.rb +26 -0
- data/app/javascript/application.js +18 -0
- data/app/javascript/controllers/application.js +9 -0
- data/app/javascript/controllers/index.js +4 -0
- data/app/javascript/controllers/plum/blocks_editor_controller.js +275 -0
- data/app/javascript/controllers/plum/blueprint_controller.js +120 -0
- data/app/javascript/controllers/plum/form_fields_controller.js +84 -0
- data/app/javascript/controllers/plum/image_picker_controller.js +143 -0
- data/app/javascript/controllers/plum/theme_settings_controller.js +17 -0
- data/app/models/plum/application_record.rb +5 -0
- data/app/models/plum/asset.rb +69 -0
- data/app/models/plum/content_type.rb +35 -0
- data/app/models/plum/entry.rb +67 -0
- data/app/models/plum/entry_term.rb +8 -0
- data/app/models/plum/form_definition.rb +68 -0
- data/app/models/plum/form_submission.rb +76 -0
- data/app/models/plum/global.rb +24 -0
- data/app/models/plum/nav_item.rb +58 -0
- data/app/models/plum/nav_menu.rb +24 -0
- data/app/models/plum/site.rb +112 -0
- data/app/models/plum/site_scoped.rb +17 -0
- data/app/models/plum/site_setting.rb +35 -0
- data/app/models/plum/taxonomy.rb +24 -0
- data/app/models/plum/term.rb +23 -0
- data/app/models/plum/user.rb +16 -0
- data/app/services/plum/base_blocks.rb +161 -0
- data/app/services/plum/block_editor_config.rb +65 -0
- data/app/services/plum/block_library.rb +31 -0
- data/app/services/plum/builder_renderer.rb +63 -0
- data/app/services/plum/field_expander.rb +78 -0
- data/app/services/plum/form_renderer.rb +110 -0
- data/app/services/plum/liquid_context.rb +335 -0
- data/app/services/plum/liquid_filters.rb +58 -0
- data/app/services/plum/liquid_renderer.rb +49 -0
- data/app/services/plum/theme.rb +160 -0
- data/app/services/plum/theme_asset_path.rb +31 -0
- data/app/services/plum/theme_package_installer.rb +287 -0
- data/app/services/plum/theme_registry.rb +63 -0
- data/app/services/plum/theme_resolver.rb +55 -0
- data/app/services/plum/theme_settings_params.rb +54 -0
- data/app/themes/bagel-boy/assets/screenshot.svg +92 -0
- data/app/themes/bagel-boy/assets/theme.css +184 -0
- data/app/themes/bagel-boy/blocks/hours.liquid +4 -0
- data/app/themes/bagel-boy/blocks/menu_item.liquid +7 -0
- data/app/themes/bagel-boy/layouts/base.liquid +64 -0
- data/app/themes/bagel-boy/templates/collections/posts.liquid +32 -0
- data/app/themes/bagel-boy/templates/entries/_default.liquid +13 -0
- data/app/themes/bagel-boy/templates/entries/landing.liquid +4 -0
- data/app/themes/bagel-boy/templates/entries/pages.liquid +18 -0
- data/app/themes/bagel-boy/templates/entries/posts.liquid +8 -0
- data/app/themes/bagel-boy/templates/index.liquid +10 -0
- data/app/themes/bagel-boy/templates/search.liquid +28 -0
- data/app/themes/bagel-boy/theme.yml +47 -0
- data/app/themes/bagel-shop/assets/screenshot.svg +28 -0
- data/app/themes/bagel-shop/assets/theme.css +7 -0
- data/app/themes/bagel-shop/layouts/base.liquid +507 -0
- data/app/themes/bagel-shop/templates/entries/_default.liquid +15 -0
- data/app/themes/bagel-shop/templates/entries/pages.liquid +12 -0
- data/app/themes/bagel-shop/templates/entries/posts.liquid +19 -0
- data/app/themes/bagel-shop/templates/index.liquid +55 -0
- data/app/themes/bagel-shop/theme.yml +30 -0
- data/app/themes/default/assets/screenshot.svg +24 -0
- data/app/themes/default/assets/theme.css +89 -0
- data/app/themes/default/layouts/base.liquid +117 -0
- data/app/themes/default/templates/collections/_default.liquid +16 -0
- data/app/themes/default/templates/collections/posts.liquid +27 -0
- data/app/themes/default/templates/entries/_default.liquid +26 -0
- data/app/themes/default/templates/entries/landing.liquid +5 -0
- data/app/themes/default/templates/entries/pages.liquid +17 -0
- data/app/themes/default/templates/entries/posts.liquid +20 -0
- data/app/themes/default/templates/index.liquid +22 -0
- data/app/themes/default/templates/search.liquid +28 -0
- data/app/themes/default/templates/taxonomies/_default.liquid +25 -0
- data/app/themes/default/templates/taxonomies/_default_index.liquid +14 -0
- data/app/themes/default/theme.yml +23 -0
- data/app/views/layouts/plum/cp.html.erb +138 -0
- data/app/views/layouts/plum/session.html.erb +43 -0
- data/app/views/plum/cp/assets/_form.html.erb +44 -0
- data/app/views/plum/cp/assets/edit.html.erb +14 -0
- data/app/views/plum/cp/assets/index.html.erb +52 -0
- data/app/views/plum/cp/assets/new.html.erb +9 -0
- data/app/views/plum/cp/content_types/_form.html.erb +113 -0
- data/app/views/plum/cp/content_types/edit.html.erb +8 -0
- data/app/views/plum/cp/content_types/index.html.erb +48 -0
- data/app/views/plum/cp/content_types/new.html.erb +5 -0
- data/app/views/plum/cp/content_types/show.html.erb +59 -0
- data/app/views/plum/cp/dashboard/show.html.erb +50 -0
- data/app/views/plum/cp/entries/_form.html.erb +196 -0
- data/app/views/plum/cp/entries/edit.html.erb +9 -0
- data/app/views/plum/cp/entries/index.html.erb +51 -0
- data/app/views/plum/cp/entries/new.html.erb +5 -0
- data/app/views/plum/cp/form_definitions/_form.html.erb +90 -0
- data/app/views/plum/cp/form_definitions/edit.html.erb +11 -0
- data/app/views/plum/cp/form_definitions/index.html.erb +43 -0
- data/app/views/plum/cp/form_definitions/new.html.erb +5 -0
- data/app/views/plum/cp/form_definitions/show.html.erb +70 -0
- data/app/views/plum/cp/form_submissions/show.html.erb +20 -0
- data/app/views/plum/cp/globals/_form.html.erb +44 -0
- data/app/views/plum/cp/globals/edit.html.erb +11 -0
- data/app/views/plum/cp/globals/index.html.erb +41 -0
- data/app/views/plum/cp/globals/new.html.erb +5 -0
- data/app/views/plum/cp/globals/show.html.erb +14 -0
- data/app/views/plum/cp/nav_items/_form.html.erb +56 -0
- data/app/views/plum/cp/nav_items/edit.html.erb +11 -0
- data/app/views/plum/cp/nav_items/new.html.erb +6 -0
- data/app/views/plum/cp/nav_menus/_form.html.erb +33 -0
- data/app/views/plum/cp/nav_menus/_nav_item.html.erb +24 -0
- data/app/views/plum/cp/nav_menus/edit.html.erb +11 -0
- data/app/views/plum/cp/nav_menus/index.html.erb +41 -0
- data/app/views/plum/cp/nav_menus/new.html.erb +5 -0
- data/app/views/plum/cp/nav_menus/show.html.erb +24 -0
- data/app/views/plum/cp/shared/_icon.html.erb +39 -0
- data/app/views/plum/cp/shared/_image_picker.html.erb +38 -0
- data/app/views/plum/cp/site_settings/edit.html.erb +145 -0
- data/app/views/plum/cp/site_settings/show.html.erb +62 -0
- data/app/views/plum/cp/taxonomies/_form.html.erb +38 -0
- data/app/views/plum/cp/taxonomies/edit.html.erb +2 -0
- data/app/views/plum/cp/taxonomies/index.html.erb +38 -0
- data/app/views/plum/cp/taxonomies/new.html.erb +2 -0
- data/app/views/plum/cp/taxonomies/show.html.erb +46 -0
- data/app/views/plum/cp/terms/_form.html.erb +30 -0
- data/app/views/plum/cp/terms/edit.html.erb +2 -0
- data/app/views/plum/cp/terms/new.html.erb +2 -0
- data/app/views/plum/cp/themes/index.html.erb +160 -0
- data/app/views/plum/form_mailer/submission_notification.html.erb +13 -0
- data/app/views/plum/form_mailer/submission_notification.text.erb +7 -0
- data/app/views/plum/sessions/new.html.erb +20 -0
- data/compat/plum-cms.rb +1 -0
- data/config/locales/en.yml +31 -0
- data/config/plum_importmap.rb +4 -0
- data/config/plum_routes.rb +34 -0
- data/db/engine_migrate/20260101000001_create_plum_tables.rb +154 -0
- data/lib/generators/plum/install/install_generator.rb +54 -0
- data/lib/generators/plum/install/templates/plum_initializer.rb +37 -0
- data/lib/plum/configuration.rb +88 -0
- data/lib/plum/content_source.rb +45 -0
- data/lib/plum/content_source_context.rb +30 -0
- data/lib/plum/content_source_registry.rb +120 -0
- data/lib/plum/engine.rb +30 -0
- data/lib/plum/liquid_tags/form_tag.rb +17 -0
- data/lib/plum/version.rb +7 -0
- data/lib/plum.rb +11 -0
- data/vendor/javascript/lexxy.js +11859 -0
- metadata +405 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/* Default theme styles */
|
|
2
|
+
|
|
3
|
+
:root {
|
|
4
|
+
color-scheme: light;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.plum-powered img {
|
|
8
|
+
max-width: 100%;
|
|
9
|
+
height: auto;
|
|
10
|
+
object-fit: contain;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* --- Blocks (page builder sections) --- */
|
|
14
|
+
.plum-block {
|
|
15
|
+
margin: 2.5rem 0;
|
|
16
|
+
}
|
|
17
|
+
.plum-block-hero {
|
|
18
|
+
text-align: center;
|
|
19
|
+
}
|
|
20
|
+
.plum-block-hero-image {
|
|
21
|
+
width: 100%;
|
|
22
|
+
max-height: 420px;
|
|
23
|
+
object-fit: cover;
|
|
24
|
+
border-radius: 0.75rem;
|
|
25
|
+
margin-bottom: 1.5rem;
|
|
26
|
+
}
|
|
27
|
+
.plum-block-hero h2 {
|
|
28
|
+
font-size: 2.25rem;
|
|
29
|
+
margin-bottom: 0.5rem;
|
|
30
|
+
}
|
|
31
|
+
.plum-block-image img {
|
|
32
|
+
width: 100%;
|
|
33
|
+
border-radius: 0.75rem;
|
|
34
|
+
}
|
|
35
|
+
.plum-block-image figcaption {
|
|
36
|
+
margin-top: 0.5rem;
|
|
37
|
+
font-size: 0.9rem;
|
|
38
|
+
color: #666;
|
|
39
|
+
text-align: center;
|
|
40
|
+
}
|
|
41
|
+
.plum-block-image-text {
|
|
42
|
+
display: grid;
|
|
43
|
+
grid-template-columns: 1fr 1fr;
|
|
44
|
+
gap: 2rem;
|
|
45
|
+
align-items: center;
|
|
46
|
+
}
|
|
47
|
+
.plum-block-image-text.plum-image-right .plum-block-image-text-media {
|
|
48
|
+
order: 2;
|
|
49
|
+
}
|
|
50
|
+
.plum-block-image-text-media img {
|
|
51
|
+
width: 100%;
|
|
52
|
+
border-radius: 0.75rem;
|
|
53
|
+
object-fit: cover;
|
|
54
|
+
}
|
|
55
|
+
.plum-block-cta {
|
|
56
|
+
text-align: center;
|
|
57
|
+
background: #f7f5fa;
|
|
58
|
+
border-radius: 0.75rem;
|
|
59
|
+
padding: 2.5rem 1.5rem;
|
|
60
|
+
}
|
|
61
|
+
.plum-block-cta-button {
|
|
62
|
+
display: inline-block;
|
|
63
|
+
margin-top: 1rem;
|
|
64
|
+
background: var(--plum-primary, #7c3aed);
|
|
65
|
+
color: #fff;
|
|
66
|
+
text-decoration: none;
|
|
67
|
+
font-weight: 600;
|
|
68
|
+
padding: 0.7rem 1.4rem;
|
|
69
|
+
border-radius: 0.5rem;
|
|
70
|
+
}
|
|
71
|
+
.plum-block-gallery-grid {
|
|
72
|
+
display: grid;
|
|
73
|
+
grid-template-columns: repeat(3, 1fr);
|
|
74
|
+
gap: 1rem;
|
|
75
|
+
}
|
|
76
|
+
.plum-block-gallery-grid img {
|
|
77
|
+
width: 100%;
|
|
78
|
+
aspect-ratio: 1 / 1;
|
|
79
|
+
object-fit: cover;
|
|
80
|
+
border-radius: 0.5rem;
|
|
81
|
+
}
|
|
82
|
+
.plum-block-spacer.plum-spacer-small { height: 1rem; }
|
|
83
|
+
.plum-block-spacer.plum-spacer-medium { height: 2.5rem; }
|
|
84
|
+
.plum-block-spacer.plum-spacer-large { height: 5rem; }
|
|
85
|
+
@media (max-width: 640px) {
|
|
86
|
+
.plum-block-image-text { grid-template-columns: 1fr; }
|
|
87
|
+
.plum-block-image-text.plum-image-right .plum-block-image-text-media { order: 0; }
|
|
88
|
+
.plum-block-gallery-grid { grid-template-columns: 1fr 1fr; }
|
|
89
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>{{ entry.title | default: site.seo_title | default: site.name }} - {{ site.name }}</title>
|
|
7
|
+
<meta name="description" content="{{ site.seo_description }}">
|
|
8
|
+
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
|
9
|
+
<link rel="stylesheet" href="{{ 'theme.css' | theme_asset_url }}">
|
|
10
|
+
<style>
|
|
11
|
+
:root { --plum-primary: {{ site.theme_settings.accent_color | default: site.primary_color | default: "#7c3aed" }}; }
|
|
12
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
13
|
+
body {
|
|
14
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
15
|
+
line-height: 1.6;
|
|
16
|
+
color: #1a1a1a;
|
|
17
|
+
background: #fff;
|
|
18
|
+
}
|
|
19
|
+
.container { max-width: 720px; margin: 0 auto; padding: 2rem 1rem; }
|
|
20
|
+
header { border-bottom: 1px solid #eee; padding-bottom: 1rem; margin-bottom: 2rem; }
|
|
21
|
+
.site-header-main { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
|
|
22
|
+
header h1 { font-size: 1.5rem; }
|
|
23
|
+
header h1 a { color: inherit; text-decoration: none; }
|
|
24
|
+
header .site-logo { max-height: 48px; width: auto; display: block; }
|
|
25
|
+
header p { color: #666; font-size: 0.9rem; }
|
|
26
|
+
.site-nav { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.35rem 0.8rem; padding-top: 0.15rem; }
|
|
27
|
+
.site-nav a { color: #4a3d45; font-size: 0.9rem; font-weight: 600; text-decoration: none; }
|
|
28
|
+
.site-nav a:hover { color: var(--plum-primary); }
|
|
29
|
+
article h1 { font-size: 2rem; margin-bottom: 0.5rem; }
|
|
30
|
+
article .meta { color: #666; font-size: 0.9rem; margin-bottom: 2rem; }
|
|
31
|
+
article .entry-hero-image { width: 100%; margin: 1.5rem 0 2rem; border-radius: 0.5rem; }
|
|
32
|
+
article .content { line-height: 1.8; }
|
|
33
|
+
article .content h2 { margin-top: 2rem; margin-bottom: 1rem; }
|
|
34
|
+
article .content h3 { margin-top: 1.5rem; margin-bottom: 0.75rem; }
|
|
35
|
+
article .content p { margin-bottom: 1rem; }
|
|
36
|
+
article .content ul, article .content ol { margin-bottom: 1rem; padding-left: 1.5rem; }
|
|
37
|
+
article .content a { color: var(--plum-primary); }
|
|
38
|
+
.contact-section { margin-top: 2.5rem; }
|
|
39
|
+
.contact-section h2 { margin-bottom: 1rem; }
|
|
40
|
+
.plum-form { display: grid; gap: 1rem; }
|
|
41
|
+
.plum-form-field { display: grid; gap: 0.35rem; }
|
|
42
|
+
.plum-form label { color: #4a3d45; font-size: 0.9rem; font-weight: 600; }
|
|
43
|
+
.plum-form input[type="text"],
|
|
44
|
+
.plum-form input[type="email"],
|
|
45
|
+
.plum-form textarea,
|
|
46
|
+
.plum-form select {
|
|
47
|
+
width: 100%;
|
|
48
|
+
border: 1px solid #d8d0d7;
|
|
49
|
+
border-radius: 0.4rem;
|
|
50
|
+
padding: 0.65rem 0.75rem;
|
|
51
|
+
font: inherit;
|
|
52
|
+
}
|
|
53
|
+
.plum-form textarea { min-height: 8rem; }
|
|
54
|
+
.plum-form input[type="checkbox"] { width: 1rem; height: 1rem; }
|
|
55
|
+
.plum-form-submit {
|
|
56
|
+
justify-self: start;
|
|
57
|
+
border: 0;
|
|
58
|
+
border-radius: 0.4rem;
|
|
59
|
+
background: var(--plum-primary);
|
|
60
|
+
color: #fff;
|
|
61
|
+
padding: 0.7rem 1rem;
|
|
62
|
+
font-weight: 700;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
}
|
|
65
|
+
footer { margin-top: 3rem; padding-top: 1rem; border-top: 1px solid #eee; color: #666; font-size: 0.9rem; }
|
|
66
|
+
footer .plum-powered { display: inline-flex; align-items: center; gap: 0.45rem; color: #4a3d45; }
|
|
67
|
+
footer .plum-powered img { width: 1.15rem; height: 1.15rem; border-radius: 0.25rem; }
|
|
68
|
+
@media (max-width: 640px) {
|
|
69
|
+
.site-header-main { display: block; }
|
|
70
|
+
.site-nav { justify-content: flex-start; margin-top: 1rem; }
|
|
71
|
+
}
|
|
72
|
+
</style>
|
|
73
|
+
{% if site.custom_css %}
|
|
74
|
+
<style id="plum-custom-css">
|
|
75
|
+
{{ site.custom_css }}
|
|
76
|
+
</style>
|
|
77
|
+
{% endif %}
|
|
78
|
+
</head>
|
|
79
|
+
<body>
|
|
80
|
+
<div class="container">
|
|
81
|
+
<header>
|
|
82
|
+
<div class="site-header-main">
|
|
83
|
+
<div>
|
|
84
|
+
<h1>
|
|
85
|
+
<a href="{{ site.url }}">
|
|
86
|
+
{% if site.logo.url %}
|
|
87
|
+
<img class="site-logo" src="{{ site.logo.url }}" alt="{{ site.logo.alt_text | default: site.name }}">
|
|
88
|
+
{% else %}
|
|
89
|
+
{{ site.name }}
|
|
90
|
+
{% endif %}
|
|
91
|
+
</a>
|
|
92
|
+
</h1>
|
|
93
|
+
{% if site.tagline %}<p>{{ site.tagline }}</p>{% endif %}
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
{% if nav.main.items.size > 0 %}
|
|
97
|
+
<nav class="site-nav" aria-label="Main navigation">
|
|
98
|
+
{% for item in nav.main.items %}
|
|
99
|
+
<a href="{{ item.url }}">{{ item.label }}</a>
|
|
100
|
+
{% endfor %}
|
|
101
|
+
</nav>
|
|
102
|
+
{% endif %}
|
|
103
|
+
</div>
|
|
104
|
+
</header>
|
|
105
|
+
|
|
106
|
+
<main>
|
|
107
|
+
{{ content }}
|
|
108
|
+
</main>
|
|
109
|
+
|
|
110
|
+
<footer>
|
|
111
|
+
{% unless site.theme_settings.show_powered_by == false %}
|
|
112
|
+
<p class="plum-powered"><a href="{{ site.powered_by_url }}">Powered by {{ site.powered_by_name }}</a></p>
|
|
113
|
+
{% endunless %}
|
|
114
|
+
</footer>
|
|
115
|
+
</div>
|
|
116
|
+
</body>
|
|
117
|
+
</html>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<div class="plum-powered" style="max-width: 48rem; margin: 0 auto; padding: 2rem;">
|
|
2
|
+
<h1>{{ collection.title }}</h1>
|
|
3
|
+
|
|
4
|
+
{% for entry in collection.entries %}
|
|
5
|
+
<article style="margin-bottom: 2rem; padding-bottom: 2rem; border-bottom: 1px solid #eee;">
|
|
6
|
+
<h2><a href="{{ entry.url }}">{{ entry.title }}</a></h2>
|
|
7
|
+
{% if entry.published_at %}
|
|
8
|
+
<p style="color: #666; font-size: 0.875rem;">{{ entry.published_at | date: "%B %d, %Y" }}</p>
|
|
9
|
+
{% endif %}
|
|
10
|
+
</article>
|
|
11
|
+
{% endfor %}
|
|
12
|
+
|
|
13
|
+
{% if collection.entries.size == 0 %}
|
|
14
|
+
<p>No entries yet.</p>
|
|
15
|
+
{% endif %}
|
|
16
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<div class="plum-powered" style="max-width: 48rem; margin: 0 auto; padding: 2rem;">
|
|
2
|
+
<h1>{{ collection.title }}</h1>
|
|
3
|
+
|
|
4
|
+
{% for post in collection.entries %}
|
|
5
|
+
<article style="margin-bottom: 2rem; padding-bottom: 2rem; border-bottom: 1px solid #eee;">
|
|
6
|
+
<h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
|
|
7
|
+
{% if post.published_at %}
|
|
8
|
+
<p style="color: #666; font-size: 0.875rem;">{{ post.published_at | date: "%B %d, %Y" }}</p>
|
|
9
|
+
{% endif %}
|
|
10
|
+
{% if post.data.excerpt %}
|
|
11
|
+
<p>{{ post.data.excerpt }}</p>
|
|
12
|
+
{% endif %}
|
|
13
|
+
</article>
|
|
14
|
+
{% endfor %}
|
|
15
|
+
|
|
16
|
+
{% if collection.entries.size == 0 %}
|
|
17
|
+
<p>No posts yet.</p>
|
|
18
|
+
{% endif %}
|
|
19
|
+
|
|
20
|
+
{% if pagination.total_pages > 1 %}
|
|
21
|
+
<nav style="display: flex; gap: 1rem; justify-content: center; margin-top: 2rem;">
|
|
22
|
+
{% if pagination.previous_url %}<a href="{{ pagination.previous_url }}">← Previous</a>{% endif %}
|
|
23
|
+
<span>Page {{ pagination.current_page }} of {{ pagination.total_pages }}</span>
|
|
24
|
+
{% if pagination.next_url %}<a href="{{ pagination.next_url }}">Next →</a>{% endif %}
|
|
25
|
+
</nav>
|
|
26
|
+
{% endif %}
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<article>
|
|
2
|
+
<h1>{{ entry.title }}</h1>
|
|
3
|
+
{% if entry.published_at %}
|
|
4
|
+
<p class="meta">Published on {{ entry.published_at | date: "%B %d, %Y" }}</p>
|
|
5
|
+
{% endif %}
|
|
6
|
+
|
|
7
|
+
{% if entry.data.hero_image.url %}
|
|
8
|
+
<img class="entry-hero-image" src="{{ entry.data.hero_image.url }}" alt="{{ entry.data.hero_image.alt_text | default: entry.title }}">
|
|
9
|
+
{% endif %}
|
|
10
|
+
|
|
11
|
+
{% assign body_html = entry.data.body | markdown | strip %}
|
|
12
|
+
{% if body_html != "" %}
|
|
13
|
+
<div class="content prose">{{ body_html }}</div>
|
|
14
|
+
{% endif %}
|
|
15
|
+
|
|
16
|
+
{% assign sections_html = entry.data.sections | strip %}
|
|
17
|
+
{% if sections_html != "" %}
|
|
18
|
+
{{ sections_html }}
|
|
19
|
+
{% endif %}
|
|
20
|
+
|
|
21
|
+
{% if entry.data.excerpt %}
|
|
22
|
+
<div class="excerpt">
|
|
23
|
+
<p><em>{{ entry.data.excerpt }}</em></p>
|
|
24
|
+
</div>
|
|
25
|
+
{% endif %}
|
|
26
|
+
</article>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<article>
|
|
2
|
+
<h1>{{ entry.title }}</h1>
|
|
3
|
+
|
|
4
|
+
{% if entry.data.hero_image.url %}
|
|
5
|
+
<img class="entry-hero-image" src="{{ entry.data.hero_image.url }}" alt="{{ entry.data.hero_image.alt_text | default: entry.title }}">
|
|
6
|
+
{% endif %}
|
|
7
|
+
|
|
8
|
+
{% assign body_html = entry.data.body | markdown | strip %}
|
|
9
|
+
{% if body_html != "" %}
|
|
10
|
+
<div class="content prose">{{ body_html }}</div>
|
|
11
|
+
{% endif %}
|
|
12
|
+
|
|
13
|
+
{% assign sections_html = entry.data.sections | strip %}
|
|
14
|
+
{% if sections_html != "" %}
|
|
15
|
+
{{ sections_html }}
|
|
16
|
+
{% endif %}
|
|
17
|
+
</article>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<article>
|
|
2
|
+
<h1>{{ entry.title }}</h1>
|
|
3
|
+
{% if entry.published_at %}
|
|
4
|
+
<p class="meta">Published on {{ entry.published_at | date: "%B %d, %Y" }}</p>
|
|
5
|
+
{% endif %}
|
|
6
|
+
|
|
7
|
+
{% if entry.data.hero_image.url %}
|
|
8
|
+
<img class="entry-hero-image" src="{{ entry.data.hero_image.url }}" alt="{{ entry.data.hero_image.alt_text | default: entry.title }}">
|
|
9
|
+
{% endif %}
|
|
10
|
+
|
|
11
|
+
<div class="content prose">
|
|
12
|
+
{{ entry.data.body | markdown }}
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
{% if entry.data.excerpt %}
|
|
16
|
+
<aside class="excerpt">
|
|
17
|
+
<p><strong>Summary:</strong> {{ entry.data.excerpt }}</p>
|
|
18
|
+
</aside>
|
|
19
|
+
{% endif %}
|
|
20
|
+
</article>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<h1>Welcome to {{ site.name }}</h1>
|
|
2
|
+
{% if site.tagline %}
|
|
3
|
+
<p>{{ site.tagline }}</p>
|
|
4
|
+
{% endif %}
|
|
5
|
+
|
|
6
|
+
{% if entries.posts.size > 0 %}
|
|
7
|
+
<section>
|
|
8
|
+
<h2>Latest Posts</h2>
|
|
9
|
+
<ul>
|
|
10
|
+
{% for post in entries.posts %}
|
|
11
|
+
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
|
|
12
|
+
{% endfor %}
|
|
13
|
+
</ul>
|
|
14
|
+
</section>
|
|
15
|
+
{% endif %}
|
|
16
|
+
|
|
17
|
+
{% if forms.contact %}
|
|
18
|
+
<section class="contact-section">
|
|
19
|
+
<h2>Contact</h2>
|
|
20
|
+
{% form "contact" %}
|
|
21
|
+
</section>
|
|
22
|
+
{% endif %}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<div class="plum-powered" style="max-width: 48rem; margin: 0 auto; padding: 2rem;">
|
|
2
|
+
<h1>Search</h1>
|
|
3
|
+
|
|
4
|
+
<form action="/search" method="get" style="margin-bottom: 2rem;">
|
|
5
|
+
<div style="display: flex; gap: 0.5rem;">
|
|
6
|
+
<input type="text" name="q" value="{{ search.query }}" placeholder="Search…"
|
|
7
|
+
style="flex: 1; padding: 0.5rem 0.75rem; border: 1px solid #ccc; border-radius: 0.375rem;">
|
|
8
|
+
<button type="submit" style="padding: 0.5rem 1rem; background: #7c3aed; color: white; border: none; border-radius: 0.375rem; cursor: pointer;">Search</button>
|
|
9
|
+
</div>
|
|
10
|
+
</form>
|
|
11
|
+
|
|
12
|
+
{% if search.query != "" %}
|
|
13
|
+
<p style="color: #666; margin-bottom: 1.5rem;">{{ search.total }} result{% if search.total != 1 %}s{% endif %} for "{{ search.query }}"</p>
|
|
14
|
+
|
|
15
|
+
{% for entry in search.results %}
|
|
16
|
+
<article style="margin-bottom: 1.5rem; padding-bottom: 1.5rem; border-bottom: 1px solid #eee;">
|
|
17
|
+
<h2 style="margin: 0;"><a href="{{ entry.url }}">{{ entry.title }}</a></h2>
|
|
18
|
+
{% if entry.published_at %}
|
|
19
|
+
<p style="color: #666; font-size: 0.875rem; margin: 0.25rem 0;">{{ entry.published_at | date: "%B %d, %Y" }}</p>
|
|
20
|
+
{% endif %}
|
|
21
|
+
</article>
|
|
22
|
+
{% endfor %}
|
|
23
|
+
|
|
24
|
+
{% if search.total == 0 %}
|
|
25
|
+
<p>No results found.</p>
|
|
26
|
+
{% endif %}
|
|
27
|
+
{% endif %}
|
|
28
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<div class="plum-powered" style="max-width: 48rem; margin: 0 auto; padding: 2rem;">
|
|
2
|
+
<h1>{{ term.name }}</h1>
|
|
3
|
+
<p style="color: #666; margin-bottom: 1.5rem;">{{ taxonomy.name }}: {{ term.name }}</p>
|
|
4
|
+
|
|
5
|
+
{% for entry in collection.entries %}
|
|
6
|
+
<article style="margin-bottom: 2rem; padding-bottom: 2rem; border-bottom: 1px solid #eee;">
|
|
7
|
+
<h2><a href="{{ entry.url }}">{{ entry.title }}</a></h2>
|
|
8
|
+
{% if entry.published_at %}
|
|
9
|
+
<p style="color: #666; font-size: 0.875rem;">{{ entry.published_at | date: "%B %d, %Y" }}</p>
|
|
10
|
+
{% endif %}
|
|
11
|
+
</article>
|
|
12
|
+
{% endfor %}
|
|
13
|
+
|
|
14
|
+
{% if collection.entries.size == 0 %}
|
|
15
|
+
<p>No entries in this category.</p>
|
|
16
|
+
{% endif %}
|
|
17
|
+
|
|
18
|
+
{% if pagination.total_pages > 1 %}
|
|
19
|
+
<nav style="display: flex; gap: 1rem; justify-content: center; margin-top: 2rem;">
|
|
20
|
+
{% if pagination.previous_url %}<a href="{{ pagination.previous_url }}">← Previous</a>{% endif %}
|
|
21
|
+
<span>Page {{ pagination.current_page }} of {{ pagination.total_pages }}</span>
|
|
22
|
+
{% if pagination.next_url %}<a href="{{ pagination.next_url }}">Next →</a>{% endif %}
|
|
23
|
+
</nav>
|
|
24
|
+
{% endif %}
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<div class="plum-powered" style="max-width: 48rem; margin: 0 auto; padding: 2rem;">
|
|
2
|
+
<h1>{{ taxonomy.name }}</h1>
|
|
3
|
+
|
|
4
|
+
{% for term in taxonomy.terms %}
|
|
5
|
+
<div style="margin-bottom: 1rem;">
|
|
6
|
+
<a href="{{ term.url }}" style="font-size: 1.125rem;">{{ term.name }}</a>
|
|
7
|
+
<span style="color: #999; font-size: 0.875rem;">({{ term.entries_count }})</span>
|
|
8
|
+
</div>
|
|
9
|
+
{% endfor %}
|
|
10
|
+
|
|
11
|
+
{% if taxonomy.terms.size == 0 %}
|
|
12
|
+
<p>No terms yet.</p>
|
|
13
|
+
{% endif %}
|
|
14
|
+
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Default
|
|
2
|
+
handle: default
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
author: Plum
|
|
5
|
+
category: Starter
|
|
6
|
+
screenshot: screenshot.svg
|
|
7
|
+
description: Clean starter theme for simple Plum sites.
|
|
8
|
+
settings:
|
|
9
|
+
fields:
|
|
10
|
+
- handle: accent_color
|
|
11
|
+
type: color
|
|
12
|
+
label: Accent Color
|
|
13
|
+
default: "#7c3aed"
|
|
14
|
+
help: Used for links and small accents.
|
|
15
|
+
- handle: show_powered_by
|
|
16
|
+
type: boolean
|
|
17
|
+
label: Show Powered By
|
|
18
|
+
default: true
|
|
19
|
+
|
|
20
|
+
# This theme adds no blocks of its own — it relies on Plum's engine-level base
|
|
21
|
+
# blocks (hero, rich_text, image, image_text, gallery, cta, button, spacer).
|
|
22
|
+
# A theme adds blocks here (handle/label/fields) + a blocks/<handle>.liquid
|
|
23
|
+
# partial, and may override a base block by reusing its handle.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" class="h-full bg-gray-50">
|
|
3
|
+
<head>
|
|
4
|
+
<title><%= Plum.configuration.cp_name %> <%= Plum.configuration.cp_subtitle %></title>
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<%= csrf_meta_tags %>
|
|
7
|
+
<%= csp_meta_tag %>
|
|
8
|
+
<%= favicon_link_tag "plum-mark.svg", type: "image/svg+xml" %>
|
|
9
|
+
<%= stylesheet_link_tag "plum/control_panel", "data-turbo-track": "reload" %>
|
|
10
|
+
<%= stylesheet_link_tag "lexxy", "data-turbo-track": "reload" %>
|
|
11
|
+
<%= javascript_importmap_tags %>
|
|
12
|
+
<script type="module">import "plum/application"</script>
|
|
13
|
+
<style>
|
|
14
|
+
:root {
|
|
15
|
+
--plum-accent: <%= Plum.configuration.cp_accent_color %>;
|
|
16
|
+
--plum-sidebar-bg: <%= Plum.configuration.cp_sidebar_bg %>;
|
|
17
|
+
--plum-sidebar-header: <%= Plum.configuration.cp_sidebar_header_bg %>;
|
|
18
|
+
--plum-sidebar-text: <%= Plum.configuration.cp_sidebar_text %>;
|
|
19
|
+
--plum-sidebar-muted: <%= Plum.configuration.cp_sidebar_muted %>;
|
|
20
|
+
}
|
|
21
|
+
.plum-sidebar { background: var(--plum-sidebar-bg); }
|
|
22
|
+
.plum-sidebar-header { background: var(--plum-sidebar-header); }
|
|
23
|
+
.plum-sidebar-link { color: var(--plum-sidebar-text); }
|
|
24
|
+
.plum-sidebar-link:hover, .plum-sidebar-link.active { background: rgba(255,255,255,0.1); color: #fff; }
|
|
25
|
+
.plum-sidebar-section { color: var(--plum-sidebar-muted); }
|
|
26
|
+
.plum-sidebar-subtitle { color: var(--plum-sidebar-text); }
|
|
27
|
+
.plum-btn-primary { background: var(--plum-accent); }
|
|
28
|
+
.plum-btn-primary:hover { filter: brightness(0.9); }
|
|
29
|
+
.plum-link { color: var(--plum-accent); }
|
|
30
|
+
.plum-link:hover { filter: brightness(0.75); }
|
|
31
|
+
|
|
32
|
+
/* Override Tailwind purple classes with accent color */
|
|
33
|
+
.bg-purple-600 { background-color: var(--plum-accent) !important; }
|
|
34
|
+
.hover\:bg-purple-700:hover { background-color: var(--plum-accent) !important; filter: brightness(0.9); }
|
|
35
|
+
.text-purple-600 { color: var(--plum-accent) !important; }
|
|
36
|
+
.hover\:text-purple-900:hover { color: var(--plum-accent) !important; filter: brightness(0.75); }
|
|
37
|
+
.focus\:ring-purple-500:focus { --tw-ring-color: var(--plum-accent) !important; }
|
|
38
|
+
.focus\:border-purple-500:focus { border-color: var(--plum-accent) !important; }
|
|
39
|
+
.border-purple-500 { border-color: var(--plum-accent) !important; }
|
|
40
|
+
</style>
|
|
41
|
+
</head>
|
|
42
|
+
<body class="h-full">
|
|
43
|
+
<div class="min-h-full">
|
|
44
|
+
<!-- Sidebar -->
|
|
45
|
+
<div class="fixed inset-y-0 left-0 w-64 plum-sidebar">
|
|
46
|
+
<div class="flex flex-col h-full">
|
|
47
|
+
<!-- Logo -->
|
|
48
|
+
<div class="flex items-center h-16 px-5 border-b border-white/10 plum-sidebar-header">
|
|
49
|
+
<%= link_to cp_root_path, class: "flex items-center gap-3 text-white" do %>
|
|
50
|
+
<%= image_tag Plum.configuration.cp_logo_path, alt: "", class: "h-9 w-9 shrink-0" %>
|
|
51
|
+
<span class="leading-tight">
|
|
52
|
+
<span class="block text-lg font-semibold tracking-normal"><%= Plum.configuration.cp_name %></span>
|
|
53
|
+
<span class="block text-xs font-medium plum-sidebar-subtitle"><%= Plum.configuration.cp_subtitle %></span>
|
|
54
|
+
</span>
|
|
55
|
+
<% end %>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<!-- Navigation -->
|
|
59
|
+
<nav class="flex-1 px-4 py-6 space-y-2 overflow-y-auto">
|
|
60
|
+
<%= link_to "Dashboard", cp_root_path,
|
|
61
|
+
class: "flex items-center px-4 py-2 text-sm font-medium rounded-md plum-sidebar-link #{request.path == cp_root_path ? 'active' : ''}" %>
|
|
62
|
+
<%= link_to root_path, target: "_blank", class: "flex items-center px-4 py-2 text-sm font-medium rounded-md plum-sidebar-link" do %>
|
|
63
|
+
View Website ↗
|
|
64
|
+
<% end %>
|
|
65
|
+
|
|
66
|
+
<div class="pt-4">
|
|
67
|
+
<p class="px-4 text-xs font-semibold plum-sidebar-section uppercase tracking-wider">Content</p>
|
|
68
|
+
<% Plum::ContentType.for_site(current_site).each do |ct| %>
|
|
69
|
+
<%= link_to cp_content_type_path(ct),
|
|
70
|
+
class: "flex items-center gap-2 px-4 py-2 mt-2 text-sm font-medium rounded-md plum-sidebar-link #{request.path.include?("/cp/content_types/#{ct.id}") ? 'active' : ''}" do %>
|
|
71
|
+
<%= render "plum/cp/shared/icon", name: ct.icon.presence || "document" %>
|
|
72
|
+
<%= ct.name %>
|
|
73
|
+
<% end %>
|
|
74
|
+
<% end %>
|
|
75
|
+
<%= link_to "+ New Type", new_cp_content_type_path,
|
|
76
|
+
class: "flex items-center px-4 py-2 mt-2 text-sm font-medium plum-sidebar-link" %>
|
|
77
|
+
<%= link_to "Assets", cp_assets_path,
|
|
78
|
+
class: "flex items-center px-4 py-2 mt-2 text-sm font-medium rounded-md plum-sidebar-link #{request.path.include?('/cp/assets') ? 'active' : ''}" %>
|
|
79
|
+
<%= link_to "Globals", cp_globals_path,
|
|
80
|
+
class: "flex items-center px-4 py-2 mt-2 text-sm font-medium rounded-md plum-sidebar-link #{request.path.include?('/cp/globals') ? 'active' : ''}" %>
|
|
81
|
+
<%= link_to "Navigation", cp_nav_menus_path,
|
|
82
|
+
class: "flex items-center px-4 py-2 mt-2 text-sm font-medium rounded-md plum-sidebar-link #{request.path.include?('/cp/nav_menus') ? 'active' : ''}" %>
|
|
83
|
+
<%= link_to "Taxonomies", "#{cp_prefix}/taxonomies",
|
|
84
|
+
class: "flex items-center px-4 py-2 mt-2 text-sm font-medium rounded-md plum-sidebar-link #{request.path.include?('/taxonomies') ? 'active' : ''}" %>
|
|
85
|
+
<%= link_to "Forms", cp_form_definitions_path,
|
|
86
|
+
class: "flex items-center px-4 py-2 mt-2 text-sm font-medium rounded-md plum-sidebar-link #{request.path.include?('/cp/forms') ? 'active' : ''}" %>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<div class="pt-4">
|
|
90
|
+
<p class="px-4 text-xs font-semibold plum-sidebar-section uppercase tracking-wider">Settings</p>
|
|
91
|
+
<%= link_to "Site Settings", cp_site_settings_path,
|
|
92
|
+
class: "flex items-center px-4 py-2 mt-2 text-sm font-medium rounded-md plum-sidebar-link #{request.path.include?('/cp/site_settings') ? 'active' : ''}" %>
|
|
93
|
+
<%= link_to "Themes", cp_themes_path,
|
|
94
|
+
class: "flex items-center px-4 py-2 mt-2 text-sm font-medium rounded-md plum-sidebar-link #{request.path.include?('/cp/themes') ? 'active' : ''}" %>
|
|
95
|
+
</div>
|
|
96
|
+
</nav>
|
|
97
|
+
|
|
98
|
+
<!-- Footer -->
|
|
99
|
+
<div class="p-4 border-t border-white/10">
|
|
100
|
+
<% if Plum.configuration.cp_back_url %>
|
|
101
|
+
<a href="<%= Plum.configuration.cp_back_url %>" class="flex items-center justify-center px-3 py-2 text-sm font-medium rounded-md plum-sidebar-link" style="background: rgba(255,255,255,0.1);">
|
|
102
|
+
<%= Plum.configuration.cp_back_label %>
|
|
103
|
+
</a>
|
|
104
|
+
<% elsif plum_managed_auth? %>
|
|
105
|
+
<div class="flex items-center">
|
|
106
|
+
<div class="flex-1 min-w-0">
|
|
107
|
+
<p class="text-sm font-medium text-white truncate"><%= current_user_label %></p>
|
|
108
|
+
<% if current_user.respond_to?(:role) %>
|
|
109
|
+
<p class="text-xs plum-sidebar-link truncate"><%= current_user.role.titleize %></p>
|
|
110
|
+
<% end %>
|
|
111
|
+
</div>
|
|
112
|
+
<%= button_to "Logout", logout_path, method: :delete,
|
|
113
|
+
class: "ml-2 px-3 py-1 text-xs font-medium plum-sidebar-link" %>
|
|
114
|
+
</div>
|
|
115
|
+
<% end %>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
<!-- Main content -->
|
|
121
|
+
<div class="pl-64">
|
|
122
|
+
<main class="py-8 px-8">
|
|
123
|
+
<% if flash[:notice] %>
|
|
124
|
+
<div class="mb-6 bg-green-50 border border-green-200 text-green-700 px-4 py-3 rounded">
|
|
125
|
+
<%= flash[:notice] %>
|
|
126
|
+
</div>
|
|
127
|
+
<% end %>
|
|
128
|
+
<% if flash[:alert] %>
|
|
129
|
+
<div class="mb-6 bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded">
|
|
130
|
+
<%= flash[:alert] %>
|
|
131
|
+
</div>
|
|
132
|
+
<% end %>
|
|
133
|
+
<%= yield %>
|
|
134
|
+
</main>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
</body>
|
|
138
|
+
</html>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" class="h-full bg-gray-100">
|
|
3
|
+
<head>
|
|
4
|
+
<title>Login - <%= Plum.configuration.cp_name %></title>
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<%= csrf_meta_tags %>
|
|
7
|
+
<%= csp_meta_tag %>
|
|
8
|
+
<%= favicon_link_tag "plum-mark.svg", type: "image/svg+xml" %>
|
|
9
|
+
<%= stylesheet_link_tag "plum/control_panel", "data-turbo-track": "reload" %>
|
|
10
|
+
<%= javascript_importmap_tags %>
|
|
11
|
+
<style>
|
|
12
|
+
:root { --plum-accent: <%= Plum.configuration.cp_accent_color %>; }
|
|
13
|
+
.bg-purple-600 { background-color: var(--plum-accent) !important; }
|
|
14
|
+
.hover\:bg-purple-700:hover { background-color: var(--plum-accent) !important; filter: brightness(0.9); }
|
|
15
|
+
.focus\:ring-purple-500:focus { --tw-ring-color: var(--plum-accent) !important; }
|
|
16
|
+
.focus\:border-purple-500:focus { border-color: var(--plum-accent) !important; }
|
|
17
|
+
</style>
|
|
18
|
+
</head>
|
|
19
|
+
<body class="h-full bg-[#F6F3EF]">
|
|
20
|
+
<div class="min-h-full flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
|
|
21
|
+
<div class="max-w-md w-full space-y-8">
|
|
22
|
+
<div>
|
|
23
|
+
<div class="flex justify-center">
|
|
24
|
+
<%= image_tag Plum.configuration.cp_logo_path, alt: Plum.configuration.cp_name, class: "h-16 w-16" %>
|
|
25
|
+
</div>
|
|
26
|
+
<h1 class="mt-4 text-center text-3xl font-bold" style="color: <%= Plum.configuration.cp_sidebar_bg %>"><%= Plum.configuration.cp_name %></h1>
|
|
27
|
+
<h2 class="mt-2 text-center text-xl text-gray-600">Sign in to your account</h2>
|
|
28
|
+
</div>
|
|
29
|
+
<% if flash[:alert] %>
|
|
30
|
+
<div class="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded">
|
|
31
|
+
<%= flash[:alert] %>
|
|
32
|
+
</div>
|
|
33
|
+
<% end %>
|
|
34
|
+
<% if flash[:notice] %>
|
|
35
|
+
<div class="bg-green-50 border border-green-200 text-green-700 px-4 py-3 rounded">
|
|
36
|
+
<%= flash[:notice] %>
|
|
37
|
+
</div>
|
|
38
|
+
<% end %>
|
|
39
|
+
<%= yield %>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</body>
|
|
43
|
+
</html>
|