panda-core 0.4.1 → 0.6.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/tailwind/application.css +95 -0
  3. data/app/assets/tailwind/tailwind.config.js +8 -0
  4. data/app/components/panda/core/UI/button.rb +45 -24
  5. data/app/components/panda/core/admin/breadcrumb_component.rb +133 -0
  6. data/app/components/panda/core/admin/button_component.rb +1 -1
  7. data/app/components/panda/core/admin/container_component.rb +27 -4
  8. data/app/components/panda/core/admin/file_gallery_component.rb +157 -0
  9. data/app/components/panda/core/admin/flash_message_component.rb +54 -36
  10. data/app/components/panda/core/admin/heading_component.rb +8 -7
  11. data/app/components/panda/core/admin/page_header_component.rb +107 -0
  12. data/app/components/panda/core/admin/panel_component.rb +1 -1
  13. data/app/components/panda/core/admin/slideover_component.rb +62 -4
  14. data/app/components/panda/core/admin/table_component.rb +11 -11
  15. data/app/components/panda/core/admin/tag_component.rb +39 -2
  16. data/app/components/panda/core/admin/user_display_component.rb +4 -5
  17. data/app/controllers/panda/core/admin/my_profile_controller.rb +2 -2
  18. data/app/controllers/panda/core/admin/sessions_controller.rb +6 -2
  19. data/app/controllers/panda/core/admin/test_sessions_controller.rb +60 -0
  20. data/app/helpers/panda/core/asset_helper.rb +31 -5
  21. data/app/helpers/panda/core/sessions_helper.rb +26 -1
  22. data/app/javascript/panda/core/application.js +8 -1
  23. data/app/javascript/panda/core/controllers/alert_controller.js +38 -0
  24. data/app/javascript/panda/core/controllers/index.js +3 -3
  25. data/app/javascript/panda/core/controllers/toggle_controller.js +41 -0
  26. data/app/javascript/panda/core/tailwindplus-elements.js +31 -0
  27. data/app/models/panda/core/user.rb +49 -6
  28. data/app/services/panda/core/attach_avatar_service.rb +67 -0
  29. data/app/views/layouts/panda/core/admin_simple.html.erb +1 -0
  30. data/app/views/panda/core/admin/my_profile/edit.html.erb +26 -1
  31. data/app/views/panda/core/admin/sessions/new.html.erb +2 -3
  32. data/app/views/panda/core/admin/shared/_breadcrumbs.html.erb +3 -3
  33. data/app/views/panda/core/admin/shared/_sidebar.html.erb +17 -12
  34. data/config/importmap.rb +15 -7
  35. data/config/routes.rb +9 -0
  36. data/db/migrate/20250811120000_add_oauth_avatar_url_to_panda_core_users.rb +7 -0
  37. data/lib/panda/core/engine.rb +12 -3
  38. data/lib/panda/core/services/base_service.rb +19 -4
  39. data/lib/panda/core/version.rb +1 -1
  40. data/lib/panda/core.rb +1 -0
  41. data/lib/tasks/panda_core_users.rake +158 -0
  42. metadata +11 -1
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :panda do
4
+ namespace :core do
5
+ namespace :users do
6
+ desc "List all users with their admin status"
7
+ task list: :environment do
8
+ users = Panda::Core::User.all.order(:email)
9
+
10
+ if users.empty?
11
+ puts "No users found."
12
+ else
13
+ puts "\nUsers:"
14
+ puts "-" * 80
15
+ users.each do |user|
16
+ admin_badge = user.admin? ? "[ADMIN]" : ""
17
+ puts "#{user.email.ljust(40)} #{admin_badge}"
18
+ end
19
+ puts "-" * 80
20
+ puts "Total: #{users.count} (#{Panda::Core::User.admins.count} admins)"
21
+ end
22
+ end
23
+
24
+ desc "Grant admin privileges to a user by email (EMAIL=user@example.com)"
25
+ task grant_admin: :environment do
26
+ email = ENV["EMAIL"]
27
+
28
+ unless email
29
+ puts "Error: EMAIL parameter is required"
30
+ puts "Usage: rails panda:core:users:grant_admin EMAIL=user@example.com"
31
+ exit 1
32
+ end
33
+
34
+ user = Panda::Core::User.find_by(email: email.downcase)
35
+
36
+ unless user
37
+ puts "Error: User with email '#{email}' not found"
38
+ puts "\nExisting users:"
39
+ Panda::Core::User.all.each do |u|
40
+ puts " - #{u.email}"
41
+ end
42
+ exit 1
43
+ end
44
+
45
+ if user.admin?
46
+ puts "User '#{user.email}' is already an admin"
47
+ else
48
+ user.update!(is_admin: true)
49
+ puts "✓ Granted admin privileges to '#{user.email}'"
50
+ end
51
+ end
52
+
53
+ desc "Revoke admin privileges from a user by email (EMAIL=user@example.com)"
54
+ task revoke_admin: :environment do
55
+ email = ENV["EMAIL"]
56
+
57
+ unless email
58
+ puts "Error: EMAIL parameter is required"
59
+ puts "Usage: rails panda:core:users:revoke_admin EMAIL=user@example.com"
60
+ exit 1
61
+ end
62
+
63
+ user = Panda::Core::User.find_by(email: email.downcase)
64
+
65
+ unless user
66
+ puts "Error: User with email '#{email}' not found"
67
+ exit 1
68
+ end
69
+
70
+ if user.admin?
71
+ # Safety check: prevent revoking the last admin
72
+ if Panda::Core::User.admins.count == 1
73
+ puts "Error: Cannot revoke admin privileges from the last admin user"
74
+ puts "Please create another admin first"
75
+ exit 1
76
+ end
77
+
78
+ user.update!(is_admin: false)
79
+ puts "✓ Revoked admin privileges from '#{user.email}'"
80
+ else
81
+ puts "User '#{user.email}' is not an admin"
82
+ end
83
+ end
84
+
85
+ desc "Create a new admin user (EMAIL=user@example.com FIRSTNAME=John LASTNAME=Doe)"
86
+ task create_admin: :environment do
87
+ email = ENV["EMAIL"]
88
+ firstname = ENV["FIRSTNAME"] || "Admin"
89
+ lastname = ENV["LASTNAME"] || "User"
90
+
91
+ unless email
92
+ puts "Error: EMAIL parameter is required"
93
+ puts "Usage: rails panda:core:users:create_admin EMAIL=user@example.com FIRSTNAME=John LASTNAME=Doe"
94
+ exit 1
95
+ end
96
+
97
+ existing_user = Panda::Core::User.find_by(email: email.downcase)
98
+
99
+ if existing_user
100
+ puts "Error: User with email '#{email}' already exists"
101
+ if existing_user.admin?
102
+ puts "This user is already an admin"
103
+ else
104
+ puts "Use 'rails panda:core:users:grant_admin EMAIL=#{email}' to make them an admin"
105
+ end
106
+ exit 1
107
+ end
108
+
109
+ # Build attributes hash based on schema
110
+ attributes = {
111
+ email: email.downcase,
112
+ is_admin: true
113
+ }
114
+
115
+ # Add name attributes based on schema
116
+ if Panda::Core::User.column_names.include?("name")
117
+ attributes[:name] = "#{firstname} #{lastname}".strip
118
+ elsif Panda::Core::User.column_names.include?("firstname") && Panda::Core::User.column_names.include?("lastname")
119
+ attributes[:firstname] = firstname
120
+ attributes[:lastname] = lastname
121
+ end
122
+
123
+ user = Panda::Core::User.create!(attributes)
124
+ puts "✓ Created admin user '#{user.email}'"
125
+ puts " Name: #{user.name}" if user.respond_to?(:name)
126
+ puts " Admin: #{user.admin?}"
127
+ end
128
+
129
+ desc "Delete a user by email (EMAIL=user@example.com)"
130
+ task delete: :environment do
131
+ email = ENV["EMAIL"]
132
+
133
+ unless email
134
+ puts "Error: EMAIL parameter is required"
135
+ puts "Usage: rails panda:core:users:delete EMAIL=user@example.com"
136
+ exit 1
137
+ end
138
+
139
+ user = Panda::Core::User.find_by(email: email.downcase)
140
+
141
+ unless user
142
+ puts "Error: User with email '#{email}' not found"
143
+ exit 1
144
+ end
145
+
146
+ # Safety check: prevent deleting the last admin
147
+ if user.admin? && Panda::Core::User.admins.count == 1
148
+ puts "Error: Cannot delete the last admin user"
149
+ puts "Please create another admin first"
150
+ exit 1
151
+ end
152
+
153
+ user.destroy!
154
+ puts "✓ Deleted user '#{email}'"
155
+ end
156
+ end
157
+ end
158
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: panda-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Otaina Limited
@@ -447,13 +447,16 @@ files:
447
447
  - app/components/panda/core/UI/badge.rb
448
448
  - app/components/panda/core/UI/button.rb
449
449
  - app/components/panda/core/UI/card.rb
450
+ - app/components/panda/core/admin/breadcrumb_component.rb
450
451
  - app/components/panda/core/admin/button_component.rb
451
452
  - app/components/panda/core/admin/container_component.rb
453
+ - app/components/panda/core/admin/file_gallery_component.rb
452
454
  - app/components/panda/core/admin/flash_message_component.rb
453
455
  - app/components/panda/core/admin/form_error_component.rb
454
456
  - app/components/panda/core/admin/form_input_component.rb
455
457
  - app/components/panda/core/admin/form_select_component.rb
456
458
  - app/components/panda/core/admin/heading_component.rb
459
+ - app/components/panda/core/admin/page_header_component.rb
457
460
  - app/components/panda/core/admin/panel_component.rb
458
461
  - app/components/panda/core/admin/slideover_component.rb
459
462
  - app/components/panda/core/admin/statistics_component.rb
@@ -468,13 +471,17 @@ files:
468
471
  - app/controllers/panda/core/admin/dashboard_controller.rb
469
472
  - app/controllers/panda/core/admin/my_profile_controller.rb
470
473
  - app/controllers/panda/core/admin/sessions_controller.rb
474
+ - app/controllers/panda/core/admin/test_sessions_controller.rb
471
475
  - app/controllers/panda/core/application_controller.rb
472
476
  - app/helpers/panda/core/asset_helper.rb
473
477
  - app/helpers/panda/core/sessions_helper.rb
474
478
  - app/javascript/panda/core/application.js
479
+ - app/javascript/panda/core/controllers/alert_controller.js
475
480
  - app/javascript/panda/core/controllers/index.js
476
481
  - app/javascript/panda/core/controllers/theme_form_controller.js
482
+ - app/javascript/panda/core/controllers/toggle_controller.js
477
483
  - app/javascript/panda/core/tailwindcss-stimulus-components.js
484
+ - app/javascript/panda/core/tailwindplus-elements.js
478
485
  - app/javascript/panda/core/vendor/@hotwired--stimulus.js
479
486
  - app/javascript/panda/core/vendor/@hotwired--turbo.js
480
487
  - app/javascript/panda/core/vendor/@rails--actioncable--src.js
@@ -482,6 +489,7 @@ files:
482
489
  - app/models/panda/core/breadcrumb.rb
483
490
  - app/models/panda/core/current.rb
484
491
  - app/models/panda/core/user.rb
492
+ - app/services/panda/core/attach_avatar_service.rb
485
493
  - app/views/layouts/panda/core/admin.html.erb
486
494
  - app/views/layouts/panda/core/admin_simple.html.erb
487
495
  - app/views/panda/core/admin/dashboard/_default_content.html.erb
@@ -499,6 +507,7 @@ files:
499
507
  - config/routes.rb
500
508
  - db/migrate/20250809000001_create_panda_core_users.rb
501
509
  - db/migrate/20250810120000_add_current_theme_to_panda_core_users.rb
510
+ - db/migrate/20250811120000_add_oauth_avatar_url_to_panda_core_users.rb
502
511
  - lib/generators/panda/core/authentication/templates/reek_spec.rb
503
512
  - lib/generators/panda/core/dev_tools/USAGE
504
513
  - lib/generators/panda/core/dev_tools/templates/lefthook.yml
@@ -532,6 +541,7 @@ files:
532
541
  - lib/tasks/panda/core/migrations.rake
533
542
  - lib/tasks/panda_core.rake
534
543
  - lib/tasks/panda_core_tasks.rake
544
+ - lib/tasks/panda_core_users.rake
535
545
  homepage: https://github.com/tastybamboo/panda-core
536
546
  licenses:
537
547
  - BSD-3-Clause