solidstats 2.0.0 → 3.0.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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -63
  3. data/README.md +27 -0
  4. data/Rakefile +3 -3
  5. data/app/assets/javascripts/solidstats/dashboard.js +0 -46
  6. data/app/assets/stylesheets/solidstats/dashboard.css +48 -0
  7. data/app/controllers/solidstats/dashboard_controller.rb +73 -61
  8. data/app/controllers/solidstats/logs_controller.rb +72 -0
  9. data/app/controllers/solidstats/performance_controller.rb +25 -0
  10. data/app/controllers/solidstats/productivity_controller.rb +39 -0
  11. data/app/controllers/solidstats/quality_controller.rb +152 -0
  12. data/app/controllers/solidstats/securities_controller.rb +30 -0
  13. data/app/helpers/solidstats/application_helper.rb +124 -11
  14. data/app/helpers/solidstats/performance_helper.rb +87 -0
  15. data/app/helpers/solidstats/productivity_helper.rb +38 -0
  16. data/app/services/solidstats/bundler_audit_service.rb +206 -0
  17. data/app/services/solidstats/coverage_compass_service.rb +335 -0
  18. data/app/services/solidstats/load_lens_service.rb +474 -0
  19. data/app/services/solidstats/log_size_monitor_service.rb +197 -66
  20. data/app/services/solidstats/my_todo_service.rb +242 -0
  21. data/app/services/solidstats/style_patrol_service.rb +319 -0
  22. data/app/views/layouts/solidstats/application.html.erb +8 -2
  23. data/app/views/layouts/solidstats/dashboard.html.erb +84 -0
  24. data/app/views/solidstats/dashboard/dashboard.html.erb +39 -0
  25. data/app/views/solidstats/logs/logs_size.html.erb +409 -0
  26. data/app/views/solidstats/performance/load_lens.html.erb +158 -0
  27. data/app/views/solidstats/productivity/_todo_list.html.erb +49 -0
  28. data/app/views/solidstats/productivity/my_todos.html.erb +84 -0
  29. data/app/views/solidstats/quality/coverage_compass.html.erb +420 -0
  30. data/app/views/solidstats/quality/style_patrol.html.erb +463 -0
  31. data/app/views/solidstats/securities/bundler_audit.html.erb +345 -0
  32. data/app/views/solidstats/shared/_dashboard_card.html.erb +160 -0
  33. data/app/views/solidstats/shared/_quick_actions.html.erb +26 -0
  34. data/config/routes.rb +31 -6
  35. data/lib/generators/solidstats/clean/clean_generator.rb +24 -0
  36. data/lib/generators/solidstats/clean/templates/README +8 -0
  37. data/lib/generators/solidstats/install/install_generator.rb +51 -10
  38. data/lib/generators/solidstats/install/templates/README +7 -0
  39. data/lib/solidstats/engine.rb +6 -71
  40. data/lib/solidstats/version.rb +1 -1
  41. data/lib/solidstats.rb +19 -303
  42. data/lib/tasks/solidstats.rake +67 -0
  43. data/lib/tasks/solidstats_performance.rake +61 -0
  44. data/lib/tasks/solidstats_tasks.rake +16 -4
  45. metadata +33 -95
  46. data/app/assets/javascripts/solidstats/gem_metadata.js +0 -554
  47. data/app/assets/stylesheets/solidstats/components/action_button.css +0 -99
  48. data/app/assets/stylesheets/solidstats/components/dashboard.css +0 -151
  49. data/app/assets/stylesheets/solidstats/components/dashboard_header.css +0 -93
  50. data/app/assets/stylesheets/solidstats/components/dashboard_layout.css +0 -97
  51. data/app/assets/stylesheets/solidstats/components/gem_metadata.css +0 -1403
  52. data/app/assets/stylesheets/solidstats/components/navigation.css +0 -80
  53. data/app/assets/stylesheets/solidstats/components/quick_navigation.css +0 -54
  54. data/app/assets/stylesheets/solidstats/components/security.css +0 -332
  55. data/app/assets/stylesheets/solidstats/components/status_badge.css +0 -58
  56. data/app/assets/stylesheets/solidstats/components/summary_card.css +0 -66
  57. data/app/assets/stylesheets/solidstats/components/tab_navigation.css +0 -95
  58. data/app/components/solidstats/base_component.rb +0 -88
  59. data/app/components/solidstats/code_quality/code_quality_section_component.html.erb +0 -0
  60. data/app/components/solidstats/code_quality/code_quality_section_component.rb +0 -0
  61. data/app/components/solidstats/code_quality/section_component.html.erb +0 -45
  62. data/app/components/solidstats/code_quality/section_component.rb +0 -34
  63. data/app/components/solidstats/dashboard_header_component.html.erb +0 -39
  64. data/app/components/solidstats/dashboard_header_component.rb +0 -33
  65. data/app/components/solidstats/previews/action_button_component_preview/button_vs_link.html.erb +0 -6
  66. data/app/components/solidstats/previews/action_button_component_preview/sizes.html.erb +0 -6
  67. data/app/components/solidstats/previews/action_button_component_preview/variants.html.erb +0 -6
  68. data/app/components/solidstats/previews/action_button_component_preview/with_icons.html.erb +0 -6
  69. data/app/components/solidstats/previews/action_button_component_preview.rb +0 -64
  70. data/app/components/solidstats/previews/navigation_component_preview.rb +0 -74
  71. data/app/components/solidstats/previews/stats_overview_component_preview.rb +0 -100
  72. data/app/components/solidstats/previews/status_badge_component_preview/sizes.html.erb +0 -6
  73. data/app/components/solidstats/previews/status_badge_component_preview/statuses.html.erb +0 -6
  74. data/app/components/solidstats/previews/status_badge_component_preview/with_icons.html.erb +0 -6
  75. data/app/components/solidstats/previews/status_badge_component_preview.rb +0 -49
  76. data/app/components/solidstats/previews/summary_card_component_preview/clickable.html.erb +0 -9
  77. data/app/components/solidstats/previews/summary_card_component_preview/dashboard_layout.html.erb +0 -9
  78. data/app/components/solidstats/previews/summary_card_component_preview/statuses.html.erb +0 -6
  79. data/app/components/solidstats/previews/summary_card_component_preview/value_formats.html.erb +0 -6
  80. data/app/components/solidstats/previews/summary_card_component_preview.rb +0 -67
  81. data/app/components/solidstats/quick_navigation_component.html.erb +0 -8
  82. data/app/components/solidstats/quick_navigation_component.rb +0 -21
  83. data/app/components/solidstats/security/gem_impact_analysis_component.html.erb +0 -44
  84. data/app/components/solidstats/security/gem_impact_analysis_component.rb +0 -45
  85. data/app/components/solidstats/security/overview_component.html.erb +0 -21
  86. data/app/components/solidstats/security/overview_component.rb +0 -104
  87. data/app/components/solidstats/security/section_component.html.erb +0 -26
  88. data/app/components/solidstats/security/section_component.rb +0 -52
  89. data/app/components/solidstats/security/timeline_component.html.erb +0 -39
  90. data/app/components/solidstats/security/timeline_component.rb +0 -43
  91. data/app/components/solidstats/tasks_section_component.html.erb +0 -17
  92. data/app/components/solidstats/tasks_section_component.rb +0 -22
  93. data/app/components/solidstats/ui/action_button_component.html.erb +0 -6
  94. data/app/components/solidstats/ui/action_button_component.rb +0 -71
  95. data/app/components/solidstats/ui/dashboard_layout_component.html.erb +0 -19
  96. data/app/components/solidstats/ui/dashboard_layout_component.rb +0 -85
  97. data/app/components/solidstats/ui/navigation_component.html.erb +0 -34
  98. data/app/components/solidstats/ui/navigation_component.rb +0 -72
  99. data/app/components/solidstats/ui/stats_overview_component.html.erb +0 -14
  100. data/app/components/solidstats/ui/stats_overview_component.rb +0 -78
  101. data/app/components/solidstats/ui/status_badge_component.html.erb +0 -6
  102. data/app/components/solidstats/ui/status_badge_component.rb +0 -42
  103. data/app/components/solidstats/ui/summary_card_component.html.erb +0 -12
  104. data/app/components/solidstats/ui/summary_card_component.rb +0 -63
  105. data/app/components/solidstats/ui/tab_navigation_component.html.erb +0 -22
  106. data/app/components/solidstats/ui/tab_navigation_component.rb +0 -79
  107. data/app/services/solidstats/audit_service.rb +0 -56
  108. data/app/services/solidstats/data_collector_service.rb +0 -83
  109. data/app/services/solidstats/gem_metadata/fetcher_service.rb +0 -136
  110. data/app/services/solidstats/todo_service.rb +0 -114
  111. data/app/views/solidstats/dashboard/_log_monitor.html.erb +0 -759
  112. data/app/views/solidstats/dashboard/_todos.html.erb +0 -151
  113. data/app/views/solidstats/dashboard/audit/_additional_styles.css +0 -22
  114. data/app/views/solidstats/dashboard/audit/_audit_badge.html.erb +0 -5
  115. data/app/views/solidstats/dashboard/audit/_audit_details.html.erb +0 -495
  116. data/app/views/solidstats/dashboard/audit/_audit_summary.html.erb +0 -26
  117. data/app/views/solidstats/dashboard/audit/_no_vulnerabilities.html.erb +0 -3
  118. data/app/views/solidstats/dashboard/audit/_security_audit.html.erb +0 -14
  119. data/app/views/solidstats/dashboard/audit/_vulnerabilities_table.html.erb +0 -1120
  120. data/app/views/solidstats/dashboard/audit/_vulnerability_details.html.erb +0 -63
  121. data/app/views/solidstats/dashboard/index.html.erb +0 -81
  122. data/app/views/solidstats/gem_metadata/_panel.html.erb +0 -419
  123. data/lib/generators/solidstats/feature/feature_generator.rb +0 -170
  124. data/lib/generators/solidstats/feature/templates/component.html.erb +0 -84
  125. data/lib/generators/solidstats/feature/templates/component.rb.erb +0 -103
  126. data/lib/generators/solidstats/feature/templates/component.scss +0 -243
  127. data/lib/generators/solidstats/feature/templates/component_test.rb.erb +0 -183
  128. data/lib/generators/solidstats/feature/templates/controller.rb.erb +0 -44
  129. data/lib/generators/solidstats/feature/templates/controller_test.rb.erb +0 -111
  130. data/lib/generators/solidstats/feature/templates/detail_view.html.erb +0 -755
  131. data/lib/generators/solidstats/feature/templates/preview.rb.erb +0 -107
  132. data/lib/generators/solidstats/feature/templates/service.rb.erb +0 -132
  133. data/lib/generators/solidstats/feature/templates/service_test.rb.erb +0 -109
  134. data/lib/generators/solidstats/install_generator.rb +0 -109
  135. data/lib/tasks/solidstats_install.rake +0 -133
@@ -1,170 +0,0 @@
1
- require "rails/generators/named_base"
2
-
3
- module Solidstats
4
- module Generators
5
- class FeatureGenerator < Rails::Generators::NamedBase
6
- source_root File.expand_path("templates", __dir__)
7
-
8
- desc "Generate a new Solidstats feature with service, component, and views"
9
-
10
- class_option :icon, type: :string, default: "📊", desc: "Icon for the feature"
11
- class_option :section, type: :string, default: "metrics", desc: "Dashboard section (overview, security, code-quality, metrics)"
12
- class_option :status_colors, type: :boolean, default: true, desc: "Include status-based coloring"
13
- class_option :cache_hours, type: :numeric, default: 1, desc: "Cache duration in hours"
14
-
15
- def create_service
16
- template "service.rb.erb", "app/services/solidstats/#{file_name}_service.rb"
17
- end
18
-
19
- def create_component_helper
20
- template "component.rb.erb", "app/helpers/solidstats/#{file_name}_helper.rb"
21
- end
22
-
23
- def create_component_partial
24
- template "component.html.erb", "app/views/solidstats/dashboard/_#{file_name}_summary.html.erb"
25
- end
26
-
27
- def create_component_styles
28
- template "component.scss", "app/assets/stylesheets/solidstats/#{file_name}_component.scss"
29
- end
30
-
31
- def create_preview
32
- template "preview.rb.erb", "app/views/solidstats/#{file_name}/preview.html.erb"
33
- end
34
-
35
- def create_detail_view
36
- template "detail_view.html.erb", "app/views/solidstats/#{file_name}/index.html.erb"
37
- end
38
-
39
- def create_controller
40
- template "controller.rb.erb", "app/controllers/solidstats/#{file_name}_controller.rb"
41
- end
42
-
43
- def create_service_test
44
- template "service_test.rb.erb", "test/services/solidstats/#{file_name}_service_test.rb"
45
- end
46
-
47
- def create_component_test
48
- template "component_test.rb.erb", "test/helpers/solidstats/#{file_name}_helper_test.rb"
49
- end
50
-
51
- def create_controller_test
52
- template "controller_test.rb.erb", "test/controllers/solidstats/#{file_name}_controller_test.rb"
53
- end
54
-
55
- def add_route
56
- route_content = " get \"#{file_name}\", to: \"#{file_name}#index\", as: :#{file_name}"
57
- inject_into_file "config/routes.rb", after: "Solidstats::Engine.routes.draw do\n" do
58
- "#{route_content}\n"
59
- end
60
- end
61
-
62
- def integrate_with_dashboard
63
- # Add instance variable to dashboard controller
64
- inject_into_file "app/controllers/solidstats/dashboard_controller.rb",
65
- after: "def index\n" do
66
- " @#{file_name}_data = #{class_name}Service.new.summary\n"
67
- end
68
-
69
- # Add to refresh method
70
- inject_into_file "app/controllers/solidstats/dashboard_controller.rb",
71
- after: "def refresh\n" do
72
- " #{file_name}_data = #{class_name}Service.new.fetch(true)\n"
73
- end
74
-
75
- # Add to refresh JSON response
76
- inject_into_file "app/controllers/solidstats/dashboard_controller.rb",
77
- after: "render json: {\n" do
78
- " #{file_name}_data: #{file_name}_data,\n"
79
- end
80
- end
81
-
82
- def update_dashboard_view
83
- # Add summary card to overview section
84
- card_partial = <<~ERB
85
-
86
- <div class="summary-card <%= @#{file_name}_data&.dig(:status) || 'status-ok' %>" data-section="#{options[:section]}" data-tab="#{file_name.dasherize}">
87
- <div class="summary-icon">#{options[:icon]}</div>
88
- <div class="summary-data">
89
- <div class="summary-value"><%= @#{file_name}_data&.dig(:value) || 0 %></div>
90
- <div class="summary-label">#{human_name}</div>
91
- </div>
92
- </div>
93
- ERB
94
-
95
- inject_into_file "app/views/solidstats/dashboard/index.html.erb",
96
- after: '<div class="stats-summary">' do
97
- card_partial
98
- end
99
-
100
- # Add section if it doesn't exist for metrics
101
- if options[:section] == "metrics"
102
- section_content = <<~ERB
103
-
104
- <!-- #{human_name} Section -->
105
- <section id="#{file_name.dasherize}" class="dashboard-section">
106
- <h2 class="section-title">#{human_name}</h2>
107
- <%= render Solidstats::#{class_name}Component.new(data: @#{file_name}_data) %>
108
- </section>
109
- ERB
110
-
111
- inject_into_file "app/views/solidstats/dashboard/index.html.erb",
112
- before: " <!-- Floating quick navigation -->" do
113
- section_content
114
- end
115
-
116
- # Add to navigation
117
- nav_item = <<~ERB
118
-
119
- <li><a href="##{file_name.dasherize}" class="nav-item" data-section="#{file_name.dasherize}">#{human_name}</a></li>
120
- ERB
121
-
122
- inject_into_file "app/views/solidstats/dashboard/index.html.erb",
123
- after: '<nav class="dashboard-nav">' do
124
- " <ul>#{nav_item}"
125
- end
126
-
127
- # Add to quick nav
128
- quick_nav_item = <<~ERB
129
-
130
- <a href="##{file_name.dasherize}" class="quick-nav-item">#{human_name}</a>
131
- ERB
132
-
133
- inject_into_file "app/views/solidstats/dashboard/index.html.erb",
134
- after: '<div class="quick-nav-menu">' do
135
- quick_nav_item
136
- end
137
- end
138
- end
139
-
140
- def create_directory_structure
141
- empty_directory "app/views/solidstats/#{file_name}"
142
- end
143
-
144
- def show_next_steps
145
- say "\n" + set_color("#{human_name} feature generated successfully!", :green, :bold)
146
- say "\nNext steps:"
147
- say " 1. Implement data collection logic in #{set_color("app/services/solidstats/#{file_name}_service.rb", :yellow)}"
148
- say " 2. Customize the component template in #{set_color("app/components/solidstats/#{file_name}_component.html.erb", :yellow)}"
149
- say " 3. Add any required styling in #{set_color("app/components/solidstats/#{file_name}_component.scss", :yellow)}"
150
- say " 4. Run tests: #{set_color("rails test test/services/solidstats/#{file_name}_service_test.rb", :cyan)}"
151
- say " 5. Visit #{set_color("http://localhost:3000/rails/view_components", :cyan)} to preview the component"
152
- say "\nThe feature will appear in the #{set_color(options[:section], :blue)} section of the dashboard."
153
- end
154
-
155
- private
156
-
157
- def human_name
158
- file_name.humanize
159
- end
160
-
161
- def class_name
162
- file_name.camelize
163
- end
164
-
165
- def section_human_name
166
- options[:section].humanize
167
- end
168
- end
169
- end
170
- end
@@ -1,84 +0,0 @@
1
- <%# <%= human_name %> Component Partial %>
2
- <%
3
- # Initialize data with defaults
4
- data ||= { value: 0, items: [], status: :ok, last_updated: Time.current }
5
-
6
- # Include helper module methods
7
- extend Solidstats::<%= class_name %>Helper
8
- %>
9
-
10
- <div class="<%= file_name.dasherize %>-component">
11
- <div class="component-header">
12
- <div class="header-main">
13
- <h3 class="component-title">
14
- <span class="component-icon"><%= options[:icon] %></span>
15
- <%= human_name %>
16
- </h3>
17
- <div class="component-status <%%= <%= file_name %>_status_class(data) %>">
18
- <span class="status-icon"><%%= <%= file_name %>_status_icon(data) %></span>
19
- <span class="status-text"><%%= <%= file_name %>_status_text(data) %></span>
20
- </div>
21
- </div>
22
- <div class="header-meta">
23
- <span class="last-updated">Last updated: <%%= <%= file_name %>_last_updated(data) %></span>
24
- </div>
25
- </div>
26
-
27
- <div class="component-content">
28
- <div class="metric-overview">
29
- <div class="metric-card primary">
30
- <div class="metric-icon"><%= options[:icon] %></div>
31
- <div class="metric-data">
32
- <div class="metric-value"><%%= <%= file_name %>_value_display(data) %></div>
33
- <div class="metric-label">Total <%= human_name %></div>
34
- </div>
35
- </div>
36
-
37
- <%% if <%= file_name %>_item_count(data) > 0 %>
38
- <div class="metric-card secondary">
39
- <div class="metric-icon">📊</div>
40
- <div class="metric-data">
41
- <div class="metric-value"><%%= <%= file_name %>_item_count(data) %></div>
42
- <div class="metric-label">Items Found</div>
43
- </div>
44
- </div>
45
- <%% end %>
46
- </div>
47
-
48
- <%% if <%= file_name %>_has_items?(data) %>
49
- <div class="items-section">
50
- <h4 class="section-title">Details</h4>
51
- <div class="items-grid">
52
- <%% data[:items].first(5).each do |item| %>
53
- <div class="item-card">
54
- <div class="item-header">
55
- <span class="item-name"><%%= item[:name] %></span>
56
- <span class="item-value"><%%= item[:value] %></span>
57
- </div>
58
- <%% if item[:category] %>
59
- <div class="item-meta">
60
- <span class="item-category"><%%= item[:category].humanize %></span>
61
- </div>
62
- <%% end %>
63
- </div>
64
- <%% end %>
65
- </div>
66
-
67
- <%% if data[:items].size > 5 %>
68
- <div class="view-all-link">
69
- <a href="<%%= solidstats.<%= file_name %>_path %>" class="action-button">
70
- <span class="action-icon">👁️</span>
71
- View All (<%%= data[:items].size %> total)
72
- </a>
73
- </div>
74
- <%% end %>
75
- </div>
76
- <%% else %>
77
- <div class="empty-state">
78
- <div class="empty-icon">🎉</div>
79
- <div class="empty-message">No <%= file_name.humanize.downcase %> items found</div>
80
- <div class="empty-description">This is good news! Everything looks clean.</div>
81
- </div>
82
- <%% end %>
83
- </div>
84
- </div>
@@ -1,103 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Helper module for <%= human_name %> component rendering
4
- # This provides data processing and helper methods for the <%= file_name %> partial
5
- module Solidstats
6
- module <%= class_name %>Helper
7
- def <%= file_name %>_status_class(data)
8
- "status-#{data[:status] || 'ok'}"
9
- end
10
-
11
- def <%= file_name %>_status_icon(data)
12
- case data[:status]&.to_sym
13
- when :good then "✅"
14
- when :warning then "⚠️"
15
- when :critical then "❌"
16
- when :info then "ℹ️"
17
- else "❓"
18
- end
19
- end
20
-
21
- def <%= file_name %>_status_text(data)
22
- case data[:status]&.to_sym
23
- when :good then "Good"
24
- when :warning then "Warning"
25
- when :critical then "Critical"
26
- when :info then "Info"
27
- else "Unknown"
28
- end
29
- end
30
-
31
- def <%= file_name %>_value_display(data)
32
- value = data[:value]
33
- return "0" unless value
34
-
35
- case value
36
- when String then value
37
- when Numeric
38
- # Format large numbers with commas
39
- if value >= 1000
40
- number_with_delimiter(value)
41
- else
42
- value.to_s
43
- end
44
- else
45
- value.to_s
46
- end
47
- end
48
-
49
- def <%= file_name %>_last_updated(data)
50
- return "Never" unless data[:last_updated]
51
-
52
- time = data[:last_updated]
53
- time = Time.parse(time) if time.is_a?(String)
54
-
55
- distance_of_time_in_words(time, Time.current) + " ago"
56
- end
57
-
58
- def <%= file_name %>_has_items?(data)
59
- data[:items].present? && data[:items].any?
60
- end
61
-
62
- def <%= file_name %>_item_count(data)
63
- return 0 unless data[:items].present?
64
- data[:items].length
65
- end
66
-
67
- def <%= file_name %>_summary_metrics(data)
68
- {
69
- value: <%= file_name %>_value_display(data),
70
- status: <%= file_name %>_status_text(data),
71
- last_updated: <%= file_name %>_last_updated(data),
72
- item_count: <%= file_name %>_item_count(data)
73
- }
74
- end
75
-
76
- def <%= file_name %>_trend_indicator(data)
77
- return "" unless data[:trend]
78
-
79
- case data[:trend]&.to_sym
80
- when :up then "📈"
81
- when :down then "📉"
82
- when :stable then "➡️"
83
- else ""
84
- end
85
- end
86
-
87
- def <%= file_name %>_priority_class(item)
88
- return "" unless item.is_a?(Hash) && item[:priority]
89
-
90
- "priority-#{item[:priority]}"
91
- end
92
-
93
- def <%= file_name %>_format_item_value(item)
94
- return "" unless item.is_a?(Hash)
95
-
96
- if item[:value].is_a?(Numeric) && item[:value] >= 1000
97
- number_with_delimiter(item[:value])
98
- else
99
- item[:value].to_s
100
- end
101
- end
102
- end
103
- end
@@ -1,243 +0,0 @@
1
- .<%= file_name.dasherize %>-component {
2
- background-color: #fff;
3
- border-radius: 12px;
4
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
5
- overflow: hidden;
6
- margin-bottom: 1.5rem;
7
- border: 1px solid rgba(0, 0, 0, 0.05);
8
- }
9
-
10
- .component-header {
11
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
12
- color: white;
13
- padding: 1.5rem;
14
-
15
- .header-main {
16
- display: flex;
17
- justify-content: space-between;
18
- align-items: center;
19
- margin-bottom: 0.5rem;
20
- }
21
-
22
- .component-title {
23
- font-size: 1.25rem;
24
- font-weight: 600;
25
- margin: 0;
26
- display: flex;
27
- align-items: center;
28
- gap: 0.5rem;
29
- }
30
-
31
- .component-status {
32
- display: flex;
33
- align-items: center;
34
- gap: 0.5rem;
35
- padding: 0.25rem 0.75rem;
36
- border-radius: 12px;
37
- background: rgba(255, 255, 255, 0.2);
38
- font-size: 0.875rem;
39
-
40
- &.status-ok {
41
- background: rgba(40, 167, 69, 0.2);
42
- }
43
-
44
- &.status-warning {
45
- background: rgba(255, 193, 7, 0.2);
46
- }
47
-
48
- &.status-danger {
49
- background: rgba(220, 53, 69, 0.2);
50
- }
51
-
52
- &.status-error {
53
- background: rgba(108, 117, 125, 0.2);
54
- }
55
- }
56
-
57
- .header-meta {
58
- opacity: 0.9;
59
- font-size: 0.875rem;
60
- }
61
- }
62
-
63
- .component-content {
64
- padding: 1.5rem;
65
- }
66
-
67
- .metric-overview {
68
- display: grid;
69
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
70
- gap: 1rem;
71
- margin-bottom: 2rem;
72
- }
73
-
74
- .metric-card {
75
- background: white;
76
- border-radius: 8px;
77
- padding: 1.25rem;
78
- border: 1px solid #e5e7eb;
79
- display: flex;
80
- align-items: center;
81
- gap: 1rem;
82
- transition: all 0.3s ease;
83
-
84
- &:hover {
85
- transform: translateY(-2px);
86
- box-shadow: 0 8px 25px -5px rgba(0, 0, 0, 0.1);
87
- }
88
-
89
- &.primary {
90
- border-left: 4px solid #3b82f6;
91
- }
92
-
93
- &.secondary {
94
- border-left: 4px solid #10b981;
95
- }
96
-
97
- .metric-icon {
98
- font-size: 1.5rem;
99
- opacity: 0.8;
100
- }
101
-
102
- .metric-data {
103
- display: flex;
104
- flex-direction: column;
105
- gap: 0.25rem;
106
- }
107
-
108
- .metric-value {
109
- font-size: 1.75rem;
110
- font-weight: 700;
111
- color: #1f2937;
112
- line-height: 1;
113
- }
114
-
115
- .metric-label {
116
- font-size: 0.875rem;
117
- color: #6b7280;
118
- font-weight: 500;
119
- }
120
- }
121
-
122
- .items-section {
123
- .section-title {
124
- font-size: 1.125rem;
125
- font-weight: 600;
126
- margin: 0 0 1rem 0;
127
- color: #1f2937;
128
- }
129
- }
130
-
131
- .items-grid {
132
- display: grid;
133
- grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
134
- gap: 1rem;
135
- margin-bottom: 1.5rem;
136
- }
137
-
138
- .item-card {
139
- background: #f9fafb;
140
- border: 1px solid #e5e7eb;
141
- border-radius: 8px;
142
- padding: 1rem;
143
- transition: all 0.2s ease;
144
-
145
- &:hover {
146
- background: #f3f4f6;
147
- border-color: #d1d5db;
148
- }
149
-
150
- .item-header {
151
- display: flex;
152
- justify-content: space-between;
153
- align-items: center;
154
- margin-bottom: 0.5rem;
155
- }
156
-
157
- .item-name {
158
- font-weight: 500;
159
- color: #1f2937;
160
- }
161
-
162
- .item-value {
163
- font-weight: 600;
164
- color: #3b82f6;
165
- }
166
-
167
- .item-meta {
168
- font-size: 0.875rem;
169
- color: #6b7280;
170
- }
171
-
172
- .item-category {
173
- background: #e5e7eb;
174
- padding: 0.125rem 0.5rem;
175
- border-radius: 4px;
176
- font-size: 0.75rem;
177
- }
178
- }
179
-
180
- .view-all-link {
181
- text-align: center;
182
-
183
- .action-button {
184
- display: inline-flex;
185
- align-items: center;
186
- gap: 0.5rem;
187
- padding: 0.75rem 1.5rem;
188
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
189
- color: white;
190
- text-decoration: none;
191
- border-radius: 8px;
192
- font-weight: 500;
193
- transition: all 0.2s ease;
194
-
195
- &:hover {
196
- transform: translateY(-1px);
197
- box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
198
- }
199
- }
200
- }
201
-
202
- .empty-state {
203
- text-align: center;
204
- padding: 3rem 1rem;
205
- color: #6b7280;
206
-
207
- .empty-icon {
208
- font-size: 3rem;
209
- margin-bottom: 1rem;
210
- opacity: 0.7;
211
- }
212
-
213
- .empty-message {
214
- font-size: 1.25rem;
215
- font-weight: 600;
216
- color: #374151;
217
- margin-bottom: 0.5rem;
218
- }
219
-
220
- .empty-description {
221
- max-width: 400px;
222
- margin: 0 auto;
223
- }
224
- }
225
-
226
- // Responsive design
227
- @media (max-width: 768px) {
228
- .component-header {
229
- .header-main {
230
- flex-direction: column;
231
- gap: 0.75rem;
232
- align-items: flex-start;
233
- }
234
- }
235
-
236
- .metric-overview {
237
- grid-template-columns: 1fr;
238
- }
239
-
240
- .items-grid {
241
- grid-template-columns: 1fr;
242
- }
243
- }