solidcrud 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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +1285 -0
  4. data/app/assets/javascripts/controllers/dashboard_controller.js +96 -0
  5. data/app/assets/javascripts/controllers/modal_controller.js +217 -0
  6. data/app/assets/javascripts/controllers/navigation_controller.js +117 -0
  7. data/app/assets/javascripts/controllers/notification_controller.js +85 -0
  8. data/app/assets/javascripts/controllers/search_controller.js +189 -0
  9. data/app/assets/javascripts/controllers/table_controller.js +272 -0
  10. data/app/assets/javascripts/solidcrud/application.js +9475 -0
  11. data/app/assets/stylesheets/solidcrud/_components.scss +267 -0
  12. data/app/assets/stylesheets/solidcrud/_forms.scss +69 -0
  13. data/app/assets/stylesheets/solidcrud/_layout.scss +149 -0
  14. data/app/assets/stylesheets/solidcrud/_tables.scss +90 -0
  15. data/app/assets/stylesheets/solidcrud/_variables.scss +21 -0
  16. data/app/assets/stylesheets/solidcrud/application.css +10 -0
  17. data/app/assets/stylesheets/solidcrud/application.css.map +1 -0
  18. data/app/assets/stylesheets/solidcrud/application.scss +10 -0
  19. data/app/assets/stylesheets/solidcrud/temp.css.map +1 -0
  20. data/app/assets/stylesheets/solidcrud/temp2.css.map +1 -0
  21. data/app/assets/stylesheets/solidcrud/webfonts/fa-brands-400.ttf +0 -0
  22. data/app/assets/stylesheets/solidcrud/webfonts/fa-brands-400.woff2 +0 -0
  23. data/app/assets/stylesheets/solidcrud/webfonts/fa-regular-400.ttf +0 -0
  24. data/app/assets/stylesheets/solidcrud/webfonts/fa-regular-400.woff2 +0 -0
  25. data/app/assets/stylesheets/solidcrud/webfonts/fa-solid-900.ttf +0 -0
  26. data/app/assets/stylesheets/solidcrud/webfonts/fa-solid-900.woff2 +0 -0
  27. data/app/assets/stylesheets/solidcrud/webfonts/fa-v4compatibility.ttf +0 -0
  28. data/app/assets/stylesheets/solidcrud/webfonts/fa-v4compatibility.woff2 +0 -0
  29. data/app/assets/stylesheets/webfonts/fa-brands-400.ttf +0 -0
  30. data/app/assets/stylesheets/webfonts/fa-brands-400.woff2 +0 -0
  31. data/app/assets/stylesheets/webfonts/fa-regular-400.ttf +0 -0
  32. data/app/assets/stylesheets/webfonts/fa-regular-400.woff2 +0 -0
  33. data/app/assets/stylesheets/webfonts/fa-solid-900.ttf +0 -0
  34. data/app/assets/stylesheets/webfonts/fa-solid-900.woff2 +0 -0
  35. data/app/assets/stylesheets/webfonts/fa-v4compatibility.ttf +0 -0
  36. data/app/assets/stylesheets/webfonts/fa-v4compatibility.woff2 +0 -0
  37. data/app/controllers/solidcrud/admin_controller.rb +215 -0
  38. data/app/controllers/solidcrud/application_controller.rb +19 -0
  39. data/app/controllers/solidcrud/assets_controller.rb +59 -0
  40. data/app/controllers/solidcrud/sessions_controller.rb +84 -0
  41. data/app/helpers/solidcrud/application_helper.rb +153 -0
  42. data/app/javascript/solidcrud/application.js +14 -0
  43. data/app/javascript/solidcrud/controllers/crud_controller.js +64 -0
  44. data/app/javascript/solidcrud/controllers/index.js +33 -0
  45. data/app/views/layouts/solidcrud/application.html.erb +70 -0
  46. data/app/views/solidcrud/admin/edit.html.erb +294 -0
  47. data/app/views/solidcrud/admin/index.html.erb +128 -0
  48. data/app/views/solidcrud/admin/model.html.erb +353 -0
  49. data/app/views/solidcrud/admin/new.html.erb +275 -0
  50. data/app/views/solidcrud/admin/shared/_dashboard_stats.html.erb +49 -0
  51. data/app/views/solidcrud/admin/shared/_edit_form_sidebar.html.erb +9 -0
  52. data/app/views/solidcrud/admin/shared/_flash_messages.html.erb +27 -0
  53. data/app/views/solidcrud/admin/shared/_full_sidebar.html.erb +56 -0
  54. data/app/views/solidcrud/admin/shared/_modal.html.erb +45 -0
  55. data/app/views/solidcrud/admin/shared/_new_form_sidebar.html.erb +6 -0
  56. data/app/views/solidcrud/admin/shared/_record_row.html.erb +35 -0
  57. data/app/views/solidcrud/admin/shared/_records_table.html.erb +85 -0
  58. data/app/views/solidcrud/sessions/new.html.erb +262 -0
  59. data/config/routes.rb +24 -0
  60. data/lib/generators/solidcrud/install/install_generator.rb +21 -0
  61. data/lib/generators/solidcrud/install/templates/INSTALL.md +80 -0
  62. data/lib/generators/solidcrud/install/templates/solidcrud.rb +31 -0
  63. data/lib/generators/solidcrud/install_generator.rb +17 -0
  64. data/lib/generators/solidcrud/templates/solidcrud.rb +4 -0
  65. data/lib/solidcrud/authentication.rb +143 -0
  66. data/lib/solidcrud/configuration.rb +64 -0
  67. data/lib/solidcrud/engine.rb +49 -0
  68. data/lib/solidcrud/version.rb +5 -0
  69. data/lib/solidcrud.rb +10 -0
  70. metadata +177 -0
@@ -0,0 +1,49 @@
1
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
2
+ <div class="bg-white p-6 rounded-xl shadow-sm border border-slate-200/50">
3
+ <div class="flex items-center justify-between">
4
+ <div>
5
+ <p class="text-sm font-medium text-slate-600">Total Models</p>
6
+ <p class="text-3xl font-bold text-slate-900"><%= models_count %></p>
7
+ </div>
8
+ <div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center">
9
+ <span class="text-blue-600">🗄️</span>
10
+ </div>
11
+ </div>
12
+ </div>
13
+
14
+ <div class="bg-white p-6 rounded-xl shadow-sm border border-slate-200/50">
15
+ <div class="flex items-center justify-between">
16
+ <div>
17
+ <p class="text-sm font-medium text-slate-600">Rails Version</p>
18
+ <p class="text-lg font-bold text-slate-900"><%= rails_version %></p>
19
+ </div>
20
+ <div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center">
21
+ <span class="text-green-600">🌿</span>
22
+ </div>
23
+ </div>
24
+ </div>
25
+
26
+ <div class="bg-white p-6 rounded-xl shadow-sm border border-slate-200/50">
27
+ <div class="flex items-center justify-between">
28
+ <div>
29
+ <p class="text-sm font-medium text-slate-600">SolidCRUD</p>
30
+ <p class="text-lg font-bold text-slate-900"><%= Solidcrud::VERSION rescue "1.0.0" %></p>
31
+ </div>
32
+ <div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center">
33
+ <span class="text-purple-600">🧊</span>
34
+ </div>
35
+ </div>
36
+ </div>
37
+
38
+ <div class="bg-white p-6 rounded-xl shadow-sm border border-slate-200/50">
39
+ <div class="flex items-center justify-between">
40
+ <div>
41
+ <p class="text-sm font-medium text-slate-600">Database</p>
42
+ <p class="text-lg font-bold text-slate-900"><%= database_adapter %></p>
43
+ </div>
44
+ <div class="w-12 h-12 bg-orange-100 rounded-lg flex items-center justify-center">
45
+ <span class="text-orange-600">🖥️</span>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ </div>
@@ -0,0 +1,9 @@
1
+ <div class="bg-yellow-50 p-4 rounded-lg border-l-4 border-yellow-400">
2
+ <h4 class="text-sm font-medium text-yellow-800 mb-2">Editing Record</h4>
3
+ <p class="text-sm text-yellow-700">
4
+ Make changes to the <%= @model_klass.name %> record below.
5
+ </p>
6
+ <div class="mt-3">
7
+ <%= link_to 'Back to List', solidcrud.admin_model_path(@model_name), class: 'text-sm text-yellow-600 hover:text-yellow-800 underline' %>
8
+ </div>
9
+ </div>
@@ -0,0 +1,27 @@
1
+ <% if notice %>
2
+ <div class="mb-6 bg-green-50 border border-green-200 rounded-xl p-4 flex items-start space-x-3 animate-in slide-in-from-top-2 duration-300">
3
+ <div class="flex-shrink-0">
4
+ <span class="text-green-500 text-lg">✓</span>
5
+ </div>
6
+ <div class="flex-1">
7
+ <p class="text-green-800 font-medium"><%= notice %></p>
8
+ </div>
9
+ <button class="flex-shrink-0 text-green-400 hover:text-green-600 transition-colors duration-200">
10
+ <span class="text-lg">×</span>
11
+ </button>
12
+ </div>
13
+ <% end %>
14
+
15
+ <% if alert %>
16
+ <div class="mb-6 bg-red-50 border border-red-200 rounded-xl p-4 flex items-start space-x-3 animate-in slide-in-from-top-2 duration-300">
17
+ <div class="flex-shrink-0">
18
+ <span class="text-red-500 text-lg">⚠️</span>
19
+ </div>
20
+ <div class="flex-1">
21
+ <p class="text-red-800 font-medium"><%= alert %></p>
22
+ </div>
23
+ <button class="flex-shrink-0 text-red-400 hover:text-red-600 transition-colors duration-200">
24
+ <span class="text-lg">×</span>
25
+ </button>
26
+ </div>
27
+ <% end %>
@@ -0,0 +1,56 @@
1
+ <div class="w-80 bg-white border-r border-slate-200/50 flex flex-col" data-controller="navigation">
2
+ <!-- Logo Section -->
3
+ <div class="p-6 border-b border-slate-200/50">
4
+ <div class="flex items-center space-x-3">
5
+ <div class="w-10 h-10 bg-gradient-to-r from-blue-500 to-purple-600 rounded-lg flex items-center justify-center">
6
+ <span class="text-white">🧊</span>
7
+ </div>
8
+ <div>
9
+ <h2 class="text-lg font-bold text-slate-900">SolidCRUD</h2>
10
+ <p class="text-xs text-slate-500">Admin Panel</p>
11
+ </div>
12
+ </div>
13
+ </div>
14
+
15
+ <!-- Navigation Menu -->
16
+ <nav class="flex-1 p-4">
17
+ <div class="space-y-1">
18
+ <a href="<%= solidcrud.root_path %>"
19
+ class="nav-item flex items-center space-x-3 px-4 py-3 text-slate-700 hover:bg-slate-100 rounded-xl transition-all duration-200 group"
20
+ data-path="/admin"
21
+ data-action="navigation#handleNavClick">
22
+ <div class="w-8 h-8 bg-slate-100 rounded-lg flex items-center justify-center group-hover:bg-blue-100 transition-colors duration-200">
23
+ <span class="text-slate-500 group-hover:text-blue-600">📊</span>
24
+ </div>
25
+ <span class="font-medium">Dashboard</span>
26
+ </a>
27
+
28
+ <div class="pt-4">
29
+ <h3 class="px-4 text-xs font-semibold text-slate-500 uppercase tracking-wider mb-2">Models</h3>
30
+ <div class="space-y-1">
31
+ <% @models.each do |model| %>
32
+ <a href="<%= solidcrud.admin_model_path(model.name) %>"
33
+ class="nav-item flex items-center space-x-3 px-4 py-3 text-slate-700 hover:bg-slate-100 rounded-xl transition-all duration-200 group"
34
+ data-path="/admin/<%= model.name %>"
35
+ data-action="navigation#handleNavClick">
36
+ <div class="w-8 h-8 bg-slate-100 rounded-lg flex items-center justify-center group-hover:bg-blue-100 transition-colors duration-200">
37
+ <span class="text-slate-500 group-hover:text-blue-600">📋</span>
38
+ </div>
39
+ <div class="flex-1 min-w-0">
40
+ <div class="font-medium truncate"><%= model.name.pluralize %></div>
41
+ <div class="text-xs text-slate-500"><%= model.count %> records</div>
42
+ </div>
43
+ </a>
44
+ <% end %>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ </nav>
49
+
50
+ <!-- Footer -->
51
+ <div class="p-4 border-t border-slate-200/50">
52
+ <div class="text-xs text-slate-500 text-center">
53
+ Rails <%= Rails.version %> • SolidCRUD
54
+ </div>
55
+ </div>
56
+ </div>
@@ -0,0 +1,45 @@
1
+ <!-- Modal Container -->
2
+ <div id="global-modal"
3
+ data-controller="modal"
4
+ data-action="click->modal#closeOnBackdrop"
5
+ data-modal-target="container"
6
+ class="fixed inset-0 z-50 hidden items-center justify-center bg-black bg-opacity-50 transition-opacity duration-300">
7
+
8
+ <!-- Modal Content -->
9
+ <div class="relative mx-4 w-full max-w-md transform rounded-2xl bg-white shadow-2xl transition-all duration-300">
10
+
11
+ <!-- Modal Header -->
12
+ <div class="flex items-center justify-between border-b border-slate-200/50 px-6 py-4">
13
+ <h3 class="text-lg font-semibold text-slate-900" id="modal-title" data-modal-target="title">
14
+ Confirm Action
15
+ </h3>
16
+ <button id="modal-close-btn"
17
+ data-action="modal#hide"
18
+ data-modal-target="closeButton"
19
+ class="text-slate-400 hover:text-slate-600 transition-colors duration-200">
20
+ <span class="text-lg">×</span>
21
+ </button>
22
+ </div>
23
+
24
+ <!-- Modal Body -->
25
+ <div class="px-6 py-4" id="modal-body" data-modal-target="body">
26
+ <p class="text-slate-600">Are you sure you want to proceed?</p>
27
+ </div>
28
+
29
+ <!-- Modal Footer -->
30
+ <div class="flex items-center justify-end space-x-3 border-t border-slate-200/50 px-6 py-4">
31
+ <button id="modal-cancel-btn"
32
+ data-action="modal#cancel"
33
+ data-modal-target="cancelButton"
34
+ class="inline-flex items-center px-4 py-2 text-sm font-medium text-slate-700 bg-slate-100 rounded-lg hover:bg-slate-200 transition-all duration-200">
35
+ Cancel
36
+ </button>
37
+ <button id="modal-confirm-btn"
38
+ data-action="modal#confirm"
39
+ data-modal-target="confirmButton"
40
+ class="inline-flex items-center px-4 py-2 text-sm font-medium text-white rounded-lg transition-all duration-200">
41
+ Confirm
42
+ </button>
43
+ </div>
44
+ </div>
45
+ </div>
@@ -0,0 +1,6 @@
1
+ <div class="bg-blue-50 p-4 rounded-lg border-l-4 border-blue-400">
2
+ <h4 class="text-sm font-medium text-blue-800 mb-2">Creating New Record</h4>
3
+ <p class="text-sm text-blue-700">
4
+ Fill in the form below to create a new <%= @model_klass.name %> record.
5
+ </p>
6
+ </div>
@@ -0,0 +1,35 @@
1
+ <tr class="hover:bg-slate-50 transition-colors duration-200" data-table-target="row" data-id="<%= record.id %>">
2
+ <% model_klass.column_names.each do |col| %>
3
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-slate-900 column-cell column-visible"
4
+ data-column="<%= col %>"
5
+ data-table-target="column">
6
+ <%= format_value(record.send(col), col, model_klass) %>
7
+ </td>
8
+ <% end %>
9
+ <td class="px-6 py-4 whitespace-nowrap text-center">
10
+ <div class="flex items-center justify-center space-x-2">
11
+ <%= link_to solidcrud.edit_admin_model_path(model_name, record),
12
+ class: 'inline-flex items-center px-3 py-2 bg-blue-50 text-blue-700 font-medium rounded-lg hover:bg-blue-100 transition-all duration-200 hover:shadow-sm',
13
+ title: 'Edit',
14
+ data: { turbo_frame: "_top" } do %>
15
+ <span class="text-lg">✏️</span>
16
+ <% end %>
17
+
18
+ <%= link_to solidcrud.admin_model_path(model_name, id: record.id),
19
+ method: :delete,
20
+ data: {
21
+ turbo_method: :delete,
22
+ action: "modal#confirmDelete",
23
+ modal_title: "Delete #{record.class.name}",
24
+ modal_message: "Are you sure you want to delete this #{record.class.name.downcase}? This action cannot be undone.",
25
+ modal_confirm_text: "Delete",
26
+ modal_cancel_text: "Cancel",
27
+ modal_url: solidcrud.admin_model_path(model_name, id: record.id)
28
+ },
29
+ class: 'inline-flex items-center px-3 py-2 bg-red-50 text-red-700 font-medium rounded-lg hover:bg-red-100 transition-all duration-200 hover:shadow-sm',
30
+ title: 'Delete' do %>
31
+ <span class="text-lg">🗑️</span>
32
+ <% end %>
33
+ </div>
34
+ </td>
35
+ </tr>
@@ -0,0 +1,85 @@
1
+ <% if records.any? %>
2
+ <div class="overflow-x-auto">
3
+ <table class="w-full">
4
+ <thead class="bg-gradient-to-r from-slate-50 to-slate-100 border-b border-slate-200/50">
5
+ <tr>
6
+ <% model_klass.column_names.each do |col| %>
7
+ <th class="px-6 py-4 text-left text-xs font-semibold text-slate-600 uppercase tracking-wider column-header column-visible"
8
+ data-column="<%= col %>"
9
+ data-table-target="header">
10
+ <%= link_to solidcrud.admin_model_path(model_name,
11
+ search: params[:search],
12
+ sort: col,
13
+ direction: (params[:sort] == col && params[:direction] != 'desc') ? 'desc' : 'asc'
14
+ ), class: 'group flex items-center space-x-2 hover:text-slate-900 transition-colors duration-200',
15
+ data: { turbo_frame: "_top" } do %>
16
+ <span class="text-slate-400 group-hover:text-slate-600"><%= column_icon(col) %></span>
17
+ <span><%= col.humanize %></span>
18
+ <% if params[:sort] == col %>
19
+ <span class="text-blue-500"><%= params[:direction] == 'desc' ? '↓' : '↑' %></span>
20
+ <% else %>
21
+ <span class="text-slate-300 group-hover:text-slate-400">↕</span>
22
+ <% end %>
23
+ <% end %>
24
+ </th>
25
+ <% end %>
26
+ <th class="px-6 py-4 text-center text-xs font-semibold text-slate-600 uppercase tracking-wider w-32">
27
+ Actions
28
+ </th>
29
+ </tr>
30
+ </thead>
31
+
32
+ <tbody class="divide-y divide-slate-200/50">
33
+ <% records.each do |record| %>
34
+ <tr class="hover:bg-slate-50 transition-colors duration-200" data-table-target="row" data-id="<%= record.id %>">
35
+ <% model_klass.column_names.each do |col| %>
36
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-slate-900 column-cell column-visible"
37
+ data-column="<%= col %>"
38
+ data-table-target="column">
39
+ <%= format_value(record.send(col), col, model_klass) %>
40
+ </td>
41
+ <% end %>
42
+ <td class="px-6 py-4 whitespace-nowrap text-center">
43
+ <div class="flex items-center justify-center space-x-2">
44
+ <%= link_to solidcrud.edit_admin_model_path(model_name, record),
45
+ class: 'inline-flex items-center px-3 py-2 bg-blue-50 text-blue-700 font-medium rounded-lg hover:bg-blue-100 transition-all duration-200 hover:shadow-sm',
46
+ title: 'Edit',
47
+ data: { turbo_frame: "_top" } do %>
48
+ <span class="text-lg">✏️</span>
49
+ <% end %>
50
+
51
+ <%= link_to solidcrud.admin_model_path(model_name, id: record.id),
52
+ method: :delete,
53
+ data: {
54
+ turbo_method: :delete,
55
+ action: "modal#confirmDelete",
56
+ modal_title: "Delete #{record.class.name}",
57
+ modal_message: "Are you sure you want to delete this #{record.class.name.downcase}? This action cannot be undone.",
58
+ modal_confirm_text: "Delete",
59
+ modal_cancel_text: "Cancel",
60
+ modal_url: solidcrud.admin_model_path(model_name, id: record.id)
61
+ },
62
+ class: 'inline-flex items-center px-3 py-2 bg-red-50 text-red-700 font-medium rounded-lg hover:bg-red-100 transition-all duration-200 hover:shadow-sm',
63
+ title: 'Delete' do %>
64
+ <span class="text-lg">🗑️</span>
65
+ <% end %>
66
+ </div>
67
+ </td>
68
+ </tr>
69
+ <% end %>
70
+ </tbody>
71
+ </table>
72
+ </div>
73
+ <% else %>
74
+ <div class="px-6 py-16 text-center">
75
+ <div class="w-20 h-20 bg-slate-100 rounded-full flex items-center justify-center mx-auto mb-6">
76
+ <span class="text-3xl">📭</span>
77
+ </div>
78
+ <h6 class="text-xl font-semibold text-slate-900 mb-2">No <%= model_name.pluralize.downcase %> found</h6>
79
+ <p class="text-slate-500 mb-6">Get started by creating your first <%= model_name.downcase %>.</p>
80
+ <%= link_to solidcrud.new_admin_model_path(model_name),
81
+ class: "inline-flex items-center px-6 py-3 bg-gradient-to-r from-blue-500 to-purple-600 text-white font-medium rounded-xl shadow-lg hover:shadow-xl transition-all duration-200 hover:scale-105" do %>
82
+ <span class="mr-2">+</span>Create First <%= model_name %>
83
+ <% end %>
84
+ </div>
85
+ <% end %>
@@ -0,0 +1,262 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Login - SolidCRUD Admin</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <%= csrf_meta_tags %>
7
+ <%= csp_meta_tag %>
8
+
9
+ <!-- SolidCRUD Assets -->
10
+ <%= stylesheet_link_tag solidcrud_stylesheet_path, media: "all" %>
11
+ <%= javascript_include_tag solidcrud_javascript_path, defer: true %>
12
+
13
+ <!-- Font Awesome (local copy recommended for production) -->
14
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
15
+
16
+ <!-- Login Page Styles -->
17
+ <style>
18
+ .login-container {
19
+ min-height: 100vh;
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: center;
23
+ background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
24
+ padding: 1rem;
25
+ }
26
+
27
+ .login-card {
28
+ max-width: 400px;
29
+ width: 100%;
30
+ background: white;
31
+ border-radius: 0.75rem;
32
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
33
+ border: 1px solid rgba(0, 0, 0, 0.08);
34
+ padding: 2rem;
35
+ }
36
+
37
+ .login-header {
38
+ text-align: center;
39
+ margin-bottom: 2rem;
40
+ }
41
+
42
+ .login-logo {
43
+ width: 4rem;
44
+ height: 4rem;
45
+ background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
46
+ border-radius: 1rem;
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: center;
50
+ margin: 0 auto 1rem;
51
+ }
52
+
53
+ .login-logo i {
54
+ color: white;
55
+ font-size: 1.5rem;
56
+ }
57
+
58
+ .login-title {
59
+ font-size: 1.875rem;
60
+ font-weight: 700;
61
+ background: linear-gradient(135deg, #1e293b 0%, #475569 100%);
62
+ background-clip: text;
63
+ -webkit-background-clip: text;
64
+ -webkit-text-fill-color: transparent;
65
+ margin-bottom: 0.5rem;
66
+ }
67
+
68
+ .login-subtitle {
69
+ color: #64748b;
70
+ font-size: 0.875rem;
71
+ }
72
+
73
+ .form-group {
74
+ margin-bottom: 1.5rem;
75
+ }
76
+
77
+ .form-label {
78
+ display: block;
79
+ font-size: 0.875rem;
80
+ font-weight: 500;
81
+ color: #374151;
82
+ margin-bottom: 0.5rem;
83
+ }
84
+
85
+ .form-input {
86
+ width: 100%;
87
+ padding: 0.75rem 1rem;
88
+ border: 1px solid #d1d5db;
89
+ border-radius: 0.5rem;
90
+ font-size: 1rem;
91
+ transition: all 0.2s ease;
92
+ background: rgba(255, 255, 255, 0.8);
93
+ backdrop-filter: blur(4px);
94
+ }
95
+
96
+ .form-input:focus {
97
+ outline: none;
98
+ border-color: #0ea5e9;
99
+ box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.1);
100
+ background: white;
101
+ }
102
+
103
+ .btn-primary {
104
+ width: 100%;
105
+ display: flex;
106
+ justify-content: center;
107
+ padding: 0.75rem 1rem;
108
+ border: 1px solid transparent;
109
+ border-radius: 0.5rem;
110
+ font-size: 0.875rem;
111
+ font-weight: 500;
112
+ color: white;
113
+ background: linear-gradient(135deg, #0284c7 0%, #0369a1 100%);
114
+ cursor: pointer;
115
+ transition: all 0.2s ease;
116
+ transform: scale(1);
117
+ }
118
+
119
+ .btn-primary:hover {
120
+ background: linear-gradient(135deg, #0369a1 0%, #075985 100%);
121
+ transform: scale(1.02);
122
+ }
123
+
124
+ .btn-primary:focus {
125
+ outline: none;
126
+ box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.1);
127
+ }
128
+
129
+ .alert {
130
+ padding: 1rem;
131
+ border-radius: 0.5rem;
132
+ margin-bottom: 1.5rem;
133
+ display: flex;
134
+ align-items: flex-start;
135
+ gap: 0.75rem;
136
+ }
137
+
138
+ .alert-danger {
139
+ background-color: #fef2f2;
140
+ border: 1px solid #fecaca;
141
+ color: #dc2626;
142
+ }
143
+
144
+ .alert i {
145
+ font-size: 1.125rem;
146
+ margin-top: 0.125rem;
147
+ }
148
+
149
+ .auth-info {
150
+ margin-top: 1.5rem;
151
+ text-align: center;
152
+ font-size: 0.75rem;
153
+ color: #6b7280;
154
+ }
155
+
156
+ .login-footer {
157
+ text-align: center;
158
+ margin-top: 2rem;
159
+ }
160
+
161
+ .login-footer p {
162
+ font-size: 0.75rem;
163
+ color: #6b7280;
164
+ }
165
+ </style>
166
+ </head>
167
+
168
+ <body>
169
+ <div class="login-container">
170
+ <div class="login-card">
171
+ <!-- Header -->
172
+ <div class="login-header">
173
+ <div class="login-logo">
174
+ <span>🧊</span>
175
+ </div>
176
+ <h1 class="login-title">SolidCRUD Admin</h1>
177
+ <p class="login-subtitle">Sign in to access the admin panel</p>
178
+ </div>
179
+
180
+ <!-- Login Form -->
181
+ <% if [:basic_auth, :custom].include?(Solidcrud.config.auth_type) %>
182
+ <%= form_with url: solidcrud.login_path, method: :post do |f| %>
183
+ <!-- Flash Messages -->
184
+ <% if flash[:alert] %>
185
+ <div class="alert alert-danger">
186
+ <span>⚠️</span>
187
+ <div>
188
+ <p><%= flash[:alert] %></p>
189
+ </div>
190
+ </div>
191
+ <% end %>
192
+
193
+ <div class="form-group">
194
+ <label for="username" class="form-label">Username</label>
195
+ <%= f.text_field :username,
196
+ class: "form-input",
197
+ placeholder: "Enter your username",
198
+ required: true,
199
+ autofocus: true %>
200
+ </div>
201
+
202
+ <div class="form-group">
203
+ <label for="password" class="form-label">Password</label>
204
+ <%= f.password_field :password,
205
+ class: "form-input",
206
+ placeholder: "Enter your password",
207
+ required: true %>
208
+ </div>
209
+
210
+ <div class="form-group">
211
+ <%= f.submit "Sign In", class: "btn-primary" %>
212
+ </div>
213
+ <% end %>
214
+ <% else %>
215
+ <!-- Flash Messages for non-form auth types -->
216
+ <% if flash[:alert] %>
217
+ <div class="alert alert-danger">
218
+ <span>⚠️</span>
219
+ <div>
220
+ <p><%= flash[:alert] %></p>
221
+ </div>
222
+ </div>
223
+ <% end %>
224
+
225
+ <div class="form-group">
226
+ <p style="text-align: center; color: #64748b;">
227
+ <% case Solidcrud.config.auth_type %>
228
+ <% when :devise %>
229
+ Please use the Devise login system to authenticate.
230
+ <% when :jwt %>
231
+ Authentication is handled via JWT tokens in API requests.
232
+ <% else %>
233
+ Authentication method not supported for web interface.
234
+ <% end %>
235
+ </p>
236
+ </div>
237
+ <% end %>
238
+
239
+ <!-- Auth Info -->
240
+ <div class="auth-info">
241
+ <% case Solidcrud.config.auth_type %>
242
+ <% when :basic_auth %>
243
+ <p>Using basic authentication</p>
244
+ <% when :custom %>
245
+ <p>Custom authentication configured</p>
246
+ <% when :devise %>
247
+ <p>Using Devise authentication</p>
248
+ <% when :jwt %>
249
+ <p>JWT authentication required</p>
250
+ <% else %>
251
+ <p>Authentication not configured</p>
252
+ <% end %>
253
+ </div>
254
+ </div>
255
+
256
+ <!-- Footer -->
257
+ <div class="login-footer">
258
+ <p>Secure admin access for SolidCRUD</p>
259
+ </div>
260
+ </div>
261
+ </body>
262
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,24 @@
1
+ Solidcrud::Engine.routes.draw do
2
+ # Asset serving routes for API-only apps
3
+ get '/stylesheets/solidcrud/:filename', to: 'assets#stylesheet', as: :stylesheet
4
+ get '/javascripts/solidcrud/:filename', to: 'assets#javascript', as: :javascript
5
+ get '/stylesheets/webfonts/:filename', to: 'assets#webfont', as: :webfont
6
+
7
+ # Authentication routes
8
+ get '/login', to: 'sessions#new', as: :login
9
+ post '/login', to: 'sessions#create'
10
+ match '/logout', to: 'sessions#destroy', as: :logout, via: [:get, :delete]
11
+
12
+ root to: 'admin#index'
13
+ get '/dashboard_stats', to: 'admin#dashboard_stats'
14
+
15
+ # Model CRUD routes - these must come before the catch-all :model route
16
+ get '/:model/new', to: 'admin#new', as: :new_admin_model
17
+ post '/:model', to: 'admin#create'
18
+ get '/:model/:id/edit', to: 'admin#edit', as: :edit_admin_model
19
+ patch '/:model/:id', to: 'admin#update'
20
+ delete '/:model/:id', to: 'admin#destroy'
21
+
22
+ # Catch-all model route - must be last
23
+ get '/:model', to: 'admin#model', as: :admin_model
24
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/base'
4
+
5
+ module Solidcrud
6
+ module Generators
7
+ class InstallGenerator < Rails::Generators::Base
8
+ source_root File.expand_path('templates', __dir__)
9
+
10
+ desc 'Creates a SolidCRUD initializer file for authentication configuration'
11
+
12
+ def copy_initializer
13
+ template 'solidcrud.rb', 'config/initializers/solidcrud.rb'
14
+ end
15
+
16
+ def show_readme
17
+ readme 'INSTALL.md'
18
+ end
19
+ end
20
+ end
21
+ end