ahoy_panel 0.0.2 → 0.0.4

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/README.md +2 -37
  3. data/Rakefile +1 -1
  4. data/app/assets/stylesheets/ahoy_panel/application.css +15 -0
  5. data/app/views/layouts/ahoy_panel/application.html.erb +11 -13
  6. data/config/routes.rb +0 -1
  7. data/lib/ahoy_panel/engine.rb +0 -15
  8. data/lib/ahoy_panel/version.rb +1 -1
  9. data/lib/tasks/ahoy_panel_tasks.rake +0 -15
  10. metadata +11 -182
  11. data/app/assets/builds/ahoy_panel.css +0 -1
  12. data/app/assets/config/ahoy_panel_manifest.js +0 -3
  13. data/app/assets/stylesheets/ahoy_panel/application.tailwind.css +0 -13
  14. data/app/components/ahoy_panel/date_arrow_navigator_component.html.erb +0 -38
  15. data/app/components/ahoy_panel/date_arrow_navigator_component.rb +0 -12
  16. data/app/components/ahoy_panel/dropdown_component.html.erb +0 -53
  17. data/app/components/ahoy_panel/dropdown_component.rb +0 -35
  18. data/app/components/ahoy_panel/stat_box_component.html.erb +0 -22
  19. data/app/components/ahoy_panel/stat_box_component.rb +0 -13
  20. data/app/controllers/ahoy_panel/dashboard_controller.rb +0 -69
  21. data/app/helpers/ahoy_panel/country_helper.rb +0 -7
  22. data/app/helpers/ahoy_panel/heroicon_helper.rb +0 -7
  23. data/app/helpers/ahoy_panel/nav_helper.rb +0 -13
  24. data/app/javascript/ahoy_panel/application.js +0 -4
  25. data/app/javascript/ahoy_panel/controllers/application.js +0 -9
  26. data/app/javascript/ahoy_panel/controllers/date_arrow_navigator_controller.js +0 -11
  27. data/app/javascript/ahoy_panel/controllers/dropdown_controller.js +0 -18
  28. data/app/javascript/ahoy_panel/controllers/index.js +0 -11
  29. data/app/javascript/ahoy_panel/controllers/mobile_header_controller.js +0 -20
  30. data/app/models/ahoy_panel/bounce_rate_data.rb +0 -4
  31. data/app/models/ahoy_panel/stat_box_data.rb +0 -26
  32. data/app/models/ahoy_panel/total_pageviews_data.rb +0 -31
  33. data/app/models/ahoy_panel/total_visits_data.rb +0 -29
  34. data/app/models/ahoy_panel/unique_visitors_data.rb +0 -29
  35. data/app/models/ahoy_panel/view_per_visit_data.rb +0 -4
  36. data/app/models/ahoy_panel/visit_duration_data.rb +0 -4
  37. data/app/views/ahoy_panel/dashboard/index.html.erb +0 -77
  38. data/app/views/layouts/ahoy_panel/_header.html.erb +0 -82
  39. data/config/importmap.rb +0 -8
  40. data/config/initializers/heroicon.rb +0 -10
  41. data/config/initializers/inline_svg.rb +0 -5
  42. data/config/tailwind.config.js +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dec4735800a9e8c98db4809b94b0958b9f1bbf948388678be59271812178a4de
4
- data.tar.gz: c192943f89134fe5c2d7fb9ac9a9591fba880822da76f6f054a15215080ddef7
3
+ metadata.gz: 228d083731324716326b2363b912ef9263e90eab97f00e822874cfdd0f4055ca
4
+ data.tar.gz: 75479dc249271130bcc6bd7abda1ef57d2e073b0eb8e8a93f11be80b6b4feca3
5
5
  SHA512:
6
- metadata.gz: 77a341c75e76f9663ba517d8a776121674e0414717a58b740cb46663850af3afa3e8a11d990d7105370f08c4121f9dad126cde7097373ac7b6bdffe32c47f85a
7
- data.tar.gz: 35fa3a030956ae9d629e154852a1bd4d32c3c880385d8a1a85086a99a80e79792ddee0bf6e22d30f85eb30421b0ee5bbc7a20073d5b0095faf1097a7d1575990
6
+ metadata.gz: d6c8c44d16551e15efd8c440244fbc1fdf7c52acd831a662b0450983ad09edc417f2880f7e89cd6c663ea729cf76a72cb962672f39cec080d61f966148d07413
7
+ data.tar.gz: d1303756ecf587c2f2e65f30e924bc0948cafba85f95185218157ce816ea3da34c3892678096fda83b06199849ea080127c0d3c205ec3db52af8b1775cffdf56
data/README.md CHANGED
@@ -1,20 +1,8 @@
1
1
  # AhoyPanel
2
- AhoyPanel is a rails engine that will give detailed analytics on Rails apps that use ahoy to collect analytics data.
2
+ Short description and motivation.
3
3
 
4
4
  ## Usage
5
- Install the gem in your Gemfile.
6
-
7
- ```ruby
8
- gem "ahoy_panel"
9
- ```
10
-
11
- And in `config/routes.rb`
12
-
13
- ```ruby
14
- mount AhoyPanel::Engine, at: "/ahoy_panel"
15
- ```
16
-
17
- And then navigate to `/ahoy_panel` to see the dashboard.
5
+ How to use my plugin.
18
6
 
19
7
  ## Installation
20
8
  Add this line to your application's Gemfile:
@@ -36,28 +24,5 @@ $ gem install ahoy_panel
36
24
  ## Contributing
37
25
  Contribution directions go here.
38
26
 
39
- ## Running the gem locally
40
-
41
- 1. Install the gem in your locally run app
42
- 2. In routes.rb, mount the engine
43
-
44
- ```ruby
45
- mount AhoyPanel::Engine, at: "/ahoy_panel"
46
- ```
47
-
48
- 3. Run the tailwindcss watch command in the root of the gem
49
-
50
- ```bash
51
- $ bundle exec rails app:tailwindcss:watch
52
- ```
53
-
54
- 4. Run the rails server in your Rails application
55
-
56
- ```bash
57
- $ bundle exec rails s
58
- ```
59
-
60
- 5. Navigate to `/ahoy_panel` to see the dashboard
61
-
62
27
  ## License
63
28
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require "bundler/setup"
2
2
 
3
- APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
4
  load "rails/tasks/engine.rake"
5
5
 
6
6
  load "rails/tasks/statistics.rake"
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -1,19 +1,17 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
- <head>
4
- <title>AhoyPanel</title>
5
- <%= csrf_meta_tags %>
6
- <%= csp_meta_tag %>
3
+ <head>
4
+ <title>Ahoy panel</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
7
 
8
- <meta name="viewport" content="width=device-width,initial-scale=1">
9
- <%= stylesheet_link_tag "ahoy_panel", media: "all", "data-turbo-track": "reload" %>
10
- <%= javascript_importmap_tags "application-ahoy-panel" %>
8
+ <%= yield :head %>
11
9
 
12
- <%= yield :head %>
13
- </head>
10
+ <%= stylesheet_link_tag "ahoy_panel/application", media: "all" %>
11
+ </head>
12
+ <body>
14
13
 
15
- <body class="bg-gray-100 h-full">
16
- <%= render "layouts/ahoy_panel/header" %>
17
- <%= yield %>
18
- </body>
14
+ <%= yield %>
15
+
16
+ </body>
19
17
  </html>
data/config/routes.rb CHANGED
@@ -1,3 +1,2 @@
1
1
  AhoyPanel::Engine.routes.draw do
2
- root to: "dashboard#index"
3
2
  end
@@ -1,20 +1,5 @@
1
- require "importmap-rails"
2
- require "turbo-rails"
3
- require "stimulus-rails"
4
- require "view_component"
5
-
6
1
  module AhoyPanel
7
2
  class Engine < ::Rails::Engine
8
3
  isolate_namespace AhoyPanel
9
-
10
- initializer "ahoy_panel.assets" do |app|
11
- app.config.assets.paths << root.join("app/javascript")
12
- app.config.assets.precompile += %w[ahoy_panel_manifest]
13
- end
14
-
15
- initializer "ahoy_panel.importmap", before: "importmap" do |app|
16
- app.config.importmap.paths << root.join("config/importmap.rb")
17
- app.config.importmap.cache_sweepers << root.join("app/javascript")
18
- end
19
4
  end
20
5
  end
@@ -1,3 +1,3 @@
1
1
  module AhoyPanel
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -2,18 +2,3 @@
2
2
  # task :ahoy_panel do
3
3
  # # Task goes here
4
4
  # end
5
-
6
- desc "Run Tailwind task"
7
- namespace :tailwindcss do
8
- task :watch do
9
- require "tailwindcss-rails"
10
- require "tailwindcss/ruby"
11
-
12
- system "#{Tailwindcss::Ruby.executable} \
13
- -i #{AhoyPanel::Engine.root.join("app/assets/stylesheets/ahoy_panel/application.tailwind.css")} \
14
- -o #{AhoyPanel::Engine.root.join("app/assets/builds/ahoy_panel.css")} \
15
- -c #{AhoyPanel::Engine.root.join("config/tailwind.config.js")} \
16
- --minify \
17
- -w"
18
- end
19
- end
metadata CHANGED
@@ -1,170 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahoy_panel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Jeon
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-02-13 00:00:00.000000000 Z
10
+ date: 2025-02-16 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
- name: tailwindcss-rails
13
+ name: rails
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 3.3.1
18
+ version: 8.0.1
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
- - - "~>"
23
+ - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 3.3.1
26
- - !ruby/object:Gem::Dependency
27
- name: importmap-rails
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: 2.1.0
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: 2.1.0
40
- - !ruby/object:Gem::Dependency
41
- name: turbo-rails
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: 2.0.11
47
- type: :runtime
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: 2.0.11
54
- - !ruby/object:Gem::Dependency
55
- name: stimulus-rails
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: 1.3.4
61
- type: :runtime
62
- prerelease: false
63
- version_requirements: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: 1.3.4
68
- - !ruby/object:Gem::Dependency
69
- name: heroicon
70
- requirement: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: 1.0.0
75
- type: :runtime
76
- prerelease: false
77
- version_requirements: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: 1.0.0
82
- - !ruby/object:Gem::Dependency
83
- name: inline_svg
84
- requirement: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: 1.10.0
89
- type: :runtime
90
- prerelease: false
91
- version_requirements: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: 1.10.0
96
- - !ruby/object:Gem::Dependency
97
- name: chartkick
98
- requirement: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: 5.1.3
103
- type: :runtime
104
- prerelease: false
105
- version_requirements: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - "~>"
108
- - !ruby/object:Gem::Version
109
- version: 5.1.3
110
- - !ruby/object:Gem::Dependency
111
- name: groupdate
112
- requirement: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - "~>"
115
- - !ruby/object:Gem::Version
116
- version: 6.5.1
117
- type: :runtime
118
- prerelease: false
119
- version_requirements: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - "~>"
122
- - !ruby/object:Gem::Version
123
- version: 6.5.1
124
- - !ruby/object:Gem::Dependency
125
- name: countries
126
- requirement: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - "~>"
129
- - !ruby/object:Gem::Version
130
- version: 7.1.0
131
- type: :runtime
132
- prerelease: false
133
- version_requirements: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - "~>"
136
- - !ruby/object:Gem::Version
137
- version: 7.1.0
138
- - !ruby/object:Gem::Dependency
139
- name: view_component
140
- requirement: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - "~>"
143
- - !ruby/object:Gem::Version
144
- version: 3.21.0
145
- type: :runtime
146
- prerelease: false
147
- version_requirements: !ruby/object:Gem::Requirement
148
- requirements:
149
- - - "~>"
150
- - !ruby/object:Gem::Version
151
- version: 3.21.0
152
- - !ruby/object:Gem::Dependency
153
- name: rspec-rails
154
- requirement: !ruby/object:Gem::Requirement
155
- requirements:
156
- - - "~>"
157
- - !ruby/object:Gem::Version
158
- version: 7.1.0
159
- type: :development
160
- prerelease: false
161
- version_requirements: !ruby/object:Gem::Requirement
162
- requirements:
163
- - - "~>"
164
- - !ruby/object:Gem::Version
165
- version: 7.1.0
25
+ version: 8.0.1
166
26
  description: Ahoy is a great analytics tracking gem. AhoyPanel is a great dashboard
167
- for the data collected by Ahoy
27
+ for the data collected by Ahoy.
168
28
  email:
169
29
  - chris@typefast.co
170
30
  executables: []
@@ -174,45 +34,14 @@ files:
174
34
  - MIT-LICENSE
175
35
  - README.md
176
36
  - Rakefile
177
- - app/assets/builds/ahoy_panel.css
178
- - app/assets/config/ahoy_panel_manifest.js
179
- - app/assets/stylesheets/ahoy_panel/application.tailwind.css
180
- - app/components/ahoy_panel/date_arrow_navigator_component.html.erb
181
- - app/components/ahoy_panel/date_arrow_navigator_component.rb
182
- - app/components/ahoy_panel/dropdown_component.html.erb
183
- - app/components/ahoy_panel/dropdown_component.rb
184
- - app/components/ahoy_panel/stat_box_component.html.erb
185
- - app/components/ahoy_panel/stat_box_component.rb
37
+ - app/assets/stylesheets/ahoy_panel/application.css
186
38
  - app/controllers/ahoy_panel/application_controller.rb
187
- - app/controllers/ahoy_panel/dashboard_controller.rb
188
39
  - app/helpers/ahoy_panel/application_helper.rb
189
- - app/helpers/ahoy_panel/country_helper.rb
190
- - app/helpers/ahoy_panel/heroicon_helper.rb
191
- - app/helpers/ahoy_panel/nav_helper.rb
192
- - app/javascript/ahoy_panel/application.js
193
- - app/javascript/ahoy_panel/controllers/application.js
194
- - app/javascript/ahoy_panel/controllers/date_arrow_navigator_controller.js
195
- - app/javascript/ahoy_panel/controllers/dropdown_controller.js
196
- - app/javascript/ahoy_panel/controllers/index.js
197
- - app/javascript/ahoy_panel/controllers/mobile_header_controller.js
198
40
  - app/jobs/ahoy_panel/application_job.rb
199
41
  - app/mailers/ahoy_panel/application_mailer.rb
200
42
  - app/models/ahoy_panel/application_record.rb
201
- - app/models/ahoy_panel/bounce_rate_data.rb
202
- - app/models/ahoy_panel/stat_box_data.rb
203
- - app/models/ahoy_panel/total_pageviews_data.rb
204
- - app/models/ahoy_panel/total_visits_data.rb
205
- - app/models/ahoy_panel/unique_visitors_data.rb
206
- - app/models/ahoy_panel/view_per_visit_data.rb
207
- - app/models/ahoy_panel/visit_duration_data.rb
208
- - app/views/ahoy_panel/dashboard/index.html.erb
209
- - app/views/layouts/ahoy_panel/_header.html.erb
210
43
  - app/views/layouts/ahoy_panel/application.html.erb
211
- - config/importmap.rb
212
- - config/initializers/heroicon.rb
213
- - config/initializers/inline_svg.rb
214
44
  - config/routes.rb
215
- - config/tailwind.config.js
216
45
  - lib/ahoy_panel.rb
217
46
  - lib/ahoy_panel/engine.rb
218
47
  - lib/ahoy_panel/version.rb
@@ -222,7 +51,7 @@ licenses:
222
51
  - MIT
223
52
  metadata:
224
53
  homepage_uri: https://www.ahoypanel.com
225
- source_code_uri: https://github.com/typefastco/ahoy_panel.
54
+ source_code_uri: https://github.com/typefastco/ahoy_panel
226
55
  rdoc_options: []
227
56
  require_paths:
228
57
  - lib
@@ -230,7 +59,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
230
59
  requirements:
231
60
  - - ">="
232
61
  - !ruby/object:Gem::Version
233
- version: '0'
62
+ version: 3.1.0
234
63
  required_rubygems_version: !ruby/object:Gem::Requirement
235
64
  requirements:
236
65
  - - ">="
@@ -1 +0,0 @@
1
- *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:Inter var,ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}[multiple],[type=date],[type=datetime-local],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],input:where(:not([type])),select,textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}[multiple]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,input:where(:not([type])):focus,select:focus,textarea:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-year-field{padding-bottom:0;padding-top:0}select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple],[size]:where(select:not([size="1"])){background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:1rem;--tw-shadow:0 0 #0000}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}[type=checkbox]:checked,[type=radio]:checked{background-color:currentColor;background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:transparent}[type=checkbox]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0'/%3E%3C/svg%3E")}@media (forced-colors:active) {[type=checkbox]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=radio]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E")}@media (forced-colors:active) {[type=radio]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:checked:focus,[type=checkbox]:checked:hover,[type=radio]:checked:focus,[type=radio]:checked:hover{background-color:currentColor;border-color:transparent}[type=checkbox]:indeterminate{background-color:currentColor;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:transparent}@media (forced-colors:active) {[type=checkbox]:indeterminate{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{background-color:currentColor;border-color:transparent}[type=file]{background:unset;border-color:inherit;border-radius:0;border-width:0;font-size:unset;line-height:inherit;padding:0}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}.sr-only{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}.static{position:static}.absolute{position:absolute}.relative{position:relative}.-inset-0\.5{inset:-.125rem}.right-0{right:0}.isolate{isolation:isolate}.z-10{z-index:10}.mx-auto{margin-left:auto;margin-right:auto}.-ml-px{margin-left:-1px}.-mr-1{margin-right:-.25rem}.mb-2{margin-bottom:.5rem}.mb-5{margin-bottom:1.25rem}.mb-8{margin-bottom:2rem}.mt-2{margin-top:.5rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.size-5{height:1.25rem;width:1.25rem}.size-6{height:1.5rem;width:1.5rem}.h-16{height:4rem}.h-4{height:1rem}.h-8{height:2rem}.h-full{height:100%}.w-4{width:1rem}.w-48{width:12rem}.w-56{width:14rem}.w-auto{width:auto}.w-full{width:100%}.max-w-7xl{max-width:80rem}.flex-none{flex:none}.shrink-0{flex-shrink:0}.origin-top-right{transform-origin:top right}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.scale-100,.scale-95{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-95{--tw-scale-x:.95;--tw-scale-y:.95}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-4{gap:1rem}.gap-px{gap:1px}.gap-x-1{-moz-column-gap:.25rem;column-gap:.25rem}.gap-x-1\.5{-moz-column-gap:.375rem;column-gap:.375rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-2{row-gap:.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))}.divide-gray-100>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(243 244 246/var(--tw-divide-opacity,1))}.overflow-hidden{overflow:hidden}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-l-md{border-bottom-left-radius:.375rem;border-top-left-radius:.375rem}.rounded-r-md{border-bottom-right-radius:.375rem;border-top-right-radius:.375rem}.border-b-2{border-bottom-width:2px}.border-l-4{border-left-width:4px}.border-blue-500{--tw-border-opacity:1;border-color:rgb(59 130 246/var(--tw-border-opacity,1))}.border-sky-500{--tw-border-opacity:1;border-color:rgb(14 165 233/var(--tw-border-opacity,1))}.border-transparent{border-color:transparent}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-900\/5{background-color:rgba(17,24,39,.05)}.bg-sky-50{--tw-bg-opacity:1;background-color:rgb(240 249 255/var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.p-2{padding:.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-10{padding-bottom:2.5rem;padding-top:2.5rem}.py-12{padding-bottom:3rem;padding-top:3rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-5{padding-bottom:1.25rem;padding-top:1.25rem}.pb-3{padding-bottom:.75rem}.pl-3{padding-left:.75rem}.pr-4{padding-right:1rem}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.text-left{text-align:left}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl\/3{font-size:1.25rem;line-height:.75rem}.text-xs{font-size:.75rem;line-height:1rem}.text-xs\/6{font-size:.75rem;line-height:1.5rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-green-600{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-sky-700{--tw-text-opacity:1;color:rgb(3 105 161/var(--tw-text-opacity,1))}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow,.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-inset{--tw-ring-inset:inset}.ring-black\/5{--tw-ring-color:rgba(0,0,0,.05)}.ring-gray-300{--tw-ring-opacity:1;--tw-ring-color:rgb(209 213 219/var(--tw-ring-opacity,1))}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-100{transition-duration:.1s}.duration-75{transition-duration:75ms}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.hover\:border-gray-300:hover{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.hover\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.hover\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:text-gray-500:hover{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.hover\:text-gray-700:hover{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.hover\:text-gray-800:hover{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.focus\:z-10:focus{z-index:10}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-inset:focus{--tw-ring-inset:inset}.focus\:ring-sky-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(14 165 233/var(--tw-ring-opacity,1))}@media (min-width:640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:p-6{padding:1.5rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width:1024px){.lg\:ml-6{margin-left:1.5rem}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2rem*var(--tw-space-x-reverse))}.lg\:px-0{padding-left:0;padding-right:0}.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (min-width:1280px){.xl\:px-8{padding-left:2rem;padding-right:2rem}}
@@ -1,3 +0,0 @@
1
- //= link_tree ../builds/ .css
2
- //= link_directory ../../javascript/ahoy_panel .js
3
- //= link_directory ../../javascript/ahoy_panel/controllers .js
@@ -1,13 +0,0 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
4
-
5
- /*
6
-
7
- @layer components {
8
- .btn-primary {
9
- @apply py-2 px-4 bg-blue-200;
10
- }
11
- }
12
-
13
- */
@@ -1,38 +0,0 @@
1
- <span
2
- data-controller="date-arrow-navigator"
3
- class="isolate inline-flex rounded-md shadow-sm"
4
- >
5
- <%= button_tag(
6
- data: { action: "click->date-arrow-navigator#left" },
7
- class: "relative inline-flex items-center rounded-l-md bg-white px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10"
8
- ) do %>
9
- <span class="sr-only">Previous</span>
10
- <svg
11
- data-url="<%= @left_url %>"
12
- class="size-5"
13
- viewBox="0 0 20 20"
14
- fill="currentColor"
15
- aria-hidden="true"
16
- data-slot="icon"
17
- >
18
- <path fill-rule="evenodd" d="M11.78 5.22a.75.75 0 0 1 0 1.06L8.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" />
19
- </svg>
20
- <% end %>
21
- <%= button_tag(
22
- data: { action: "click->date-arrow-navigator#right" },
23
- disabled: @right_disabled,
24
- class: "relative -ml-px inline-flex items-center rounded-r-md bg-white px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10"
25
- ) do %>
26
- <span class="sr-only">Next</span>
27
- <svg
28
- data-url="<%= @right_url %>"
29
- class="size-5"
30
- viewBox="0 0 20 20"
31
- fill="currentColor"
32
- aria-hidden="true"
33
- data-slot="icon"
34
- >
35
- <path fill-rule="evenodd" d="M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
36
- </svg>
37
- <% end %>
38
- </span>
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AhoyPanel
4
- class DateArrowNavigatorComponent < ViewComponent::Base
5
- def initialize(date: Time.zone.now.to_date)
6
- @right_disabled = date.today?
7
-
8
- @left_url = "/ahoy_panel?selected_date=#{date - 1.day}"
9
- @right_url = "/ahoy_panel?selected_date=#{date + 1.day}"
10
- end
11
- end
12
- end
@@ -1,53 +0,0 @@
1
- <div
2
- data-controller="dropdown"
3
- class="relative inline-block text-left"
4
- >
5
- <div class="w-48">
6
- <button
7
- data-action="click->dropdown#open"
8
- type="button"
9
- class="inline-flex w-full justify-between gap-x-1.5 rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50" id="menu-button" aria-expanded="true" aria-haspopup="true"
10
- >
11
- <%= @label %>
12
- <svg class="-mr-1 size-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon">
13
- <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
14
- </svg>
15
- </button>
16
- </div>
17
-
18
- <!--
19
- Dropdown menu, show/hide based on menu state.
20
-
21
- Entering: "transition ease-out duration-100"
22
- From: "transform opacity-0 scale-95"
23
- To: "transform opacity-100 scale-100"
24
- Leaving: "transition ease-in duration-75"
25
- From: "transform opacity-100 scale-100"
26
- To: "transform opacity-0 scale-95"
27
- -->
28
- <div
29
- data-dropdown-target="items"
30
- data-transition-enter="transition ease-out duration-100"
31
- data-transition-enter-start="transform opacity-0 scale-95"
32
- data-transition-enter-end="transform opacity-100 scale-100"
33
- data-transition-leave="transition ease-in duration-75"
34
- data-transition-leave-start="transform opacity-100 scale-100"
35
- data-transition-leave-end="transform opacity-0 scale-95"
36
- class="hidden absolute right-0 z-10 mt-2 w-56 origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black/5 focus:outline-none"
37
- role="menu"
38
- aria-orientation="vertical"
39
- aria-labelledby="menu-button"
40
- tabindex="-1"
41
- >
42
- <!-- Active: "bg-gray-100 text-gray-900 outline-none", Not Active: "text-gray-700" -->
43
- <% @item_groups.each do |items| %>
44
- <div class="py-1" role="none">
45
- <% items.each do |item| %>
46
- <%= link_to item.label, item.url, class: item.class, role: "menuitem", tabindex: "-1" %>
47
- <% end %>
48
- </div>
49
- <% end %>
50
- </div>
51
- </div>
52
-
53
-
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AhoyPanel
4
- class DropdownComponent < ViewComponent::Base
5
- def initialize(item_groups:, date: Time.zone.now.to_date)
6
- @item_groups = build_item_groups(item_groups)
7
- @label = humanize_date(date)
8
- end
9
-
10
- private
11
-
12
- Item = Struct.new(:label, :url, :class)
13
-
14
- CLASSES = {
15
- active: "block px-4 py-2 text-sm bg-gray-100 text-gray-900 outline-none hover:bg-gray-100",
16
- inactive: "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
17
- }
18
-
19
- def build_item_groups(item_groups)
20
- item_groups.map do |items|
21
- items.map do |item|
22
- Item.new(item[:label], item[:url], CLASSES[:inactive])
23
- end
24
- end
25
- end
26
-
27
- def humanize_date(date)
28
- return "Today" if date.today?
29
-
30
- return "Yesterday" if date.yesterday?
31
-
32
- date
33
- end
34
- end
35
- end
@@ -1,22 +0,0 @@
1
- <div class="justify-between gap-x-4 gap-y-2 bg-white px-4 py-10 sm:px-6 xl:px-8">
2
- <dt class="text-xs/6 font-semibold text-gray-500 uppercase tracking-wide mb-2">
3
- <%= @title %>
4
- </dt>
5
- <div class="flex items-center gap-x-4">
6
- <dd class="flex-none text-xl/3 font-medium tracking-tight text-gray-900">
7
- <%= @data %>
8
- </dd>
9
- <% if @change.nonzero? %>
10
- <dd class="text-xs font-medium text-gray-700">
11
- <div class="flex gap-x-1">
12
- <% if @change.positive? %>
13
- <%= heroicon "arrow-up-right", options: { class: "h-4 w-4 text-green-600" } %>
14
- <% else %>
15
- <%= heroicon "arrow-down-right", options: { class: "h-4 w-4 text-red-600" } %>
16
- <% end %>
17
- <%= @change %>%
18
- </div>
19
- </dd>
20
- <% end %>
21
- </div>
22
- </div>
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AhoyPanel
4
- class StatBoxComponent < ViewComponent::Base
5
- delegate :heroicon, to: :helpers
6
-
7
- def initialize(title:, data:, change: nil)
8
- @title = title
9
- @data = data
10
- @change = change
11
- end
12
- end
13
- end
@@ -1,69 +0,0 @@
1
- module AhoyPanel
2
- class DashboardController < ApplicationController
3
- def index
4
- @dropdown_item_groups = [
5
- [{ label: "Today", url: "" }, { label: "Yesterday", url: "" }],
6
- [{ label: "Last 7 Days", url: "" }, { label: "Last 30 Days", url: "" }],
7
- [{ label: "Month to Date", url: "" }, { label: "Last Month", url: "" }],
8
- [{ label: "Year to Date", url: "" }, { label: "Last 12 Months", url: "" }],
9
- [{ label: "All Time", url: "" }, { label: "Custom Range", url: "" }],
10
- [{ label: "Compare", url: "" }],
11
- ]
12
-
13
- @selected_date = params[:selected_date]&.to_time&.to_date || Time.zone.now.to_date
14
- @date_range = date_range
15
-
16
- @visits = Ahoy::Visit.all
17
- @events = Ahoy::Event.all
18
- @visits_count = Ahoy::Visit.where("started_at > ?", 30.days.ago).size
19
- @events_count = Ahoy::Event.where("time > ?", 30.days.ago).size
20
-
21
-
22
- @unique_visitors_current = Ahoy::Visit.where(started_at: current_time_range)
23
- @unique_visitors_before = Ahoy::Visit.where(started_at: before_time_range)
24
-
25
- @total_visits_current = Ahoy::Visit.where(started_at: current_time_range)
26
- @total_visits_before = Ahoy::Visit.where(started_at: before_time_range)
27
-
28
- @unique_visitors_data = AhoyPanel::UniqueVisitorsData.new(
29
- start_at: date_range.start_at, end_at: date_range.end_at
30
- )
31
- @total_visits_data = AhoyPanel::TotalVisitsData.new(
32
- start_at: date_range.start_at, end_at: date_range.end_at
33
- )
34
- @total_pageviews_data = AhoyPanel::TotalPageviewsData.new(
35
- start_at: date_range.start_at, end_at: date_range.end_at
36
- )
37
- end
38
-
39
- private
40
-
41
- DateRange = Struct.new(:start_at, :end_at)
42
-
43
- def date_range
44
- return @date_range if defined?(@date_range)
45
-
46
- case params[:selected_date]
47
- when "blah"
48
- else
49
- @date_range = DateRange.new(Time.zone.now.beginning_of_day, Time.zone.now.end_of_day)
50
- end
51
- end
52
-
53
- def filter_date
54
- Time.zone.today
55
- end
56
-
57
- def before_date
58
- filter_date - 1.day
59
- end
60
-
61
- def current_time_range
62
- filter_date.beginning_of_day..filter_date.end_of_day
63
- end
64
-
65
- def before_time_range
66
- before_date.beginning_of_day..before_date.end_of_day
67
- end
68
- end
69
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AhoyPanel
4
- module CountryHelper
5
- EMOJI_MAP = { "AD": "🇦🇩", "AE": "🇦🇪", "AF": "🇦🇫", "AG": "🇦🇬", "AI": "🇦🇮", "AL": "🇦🇱", "AM": "🇦🇲", "AO": "🇦🇴", "AQ": "🇦🇶", "AR": "🇦🇷", "AS": "🇦🇸", "AT": "🇦🇹", "AU": "🇦🇺", "AW": "🇦🇼", "AX": "🇦🇽", "AZ": "🇦🇿", "BA": "🇧🇦", "BB": "🇧🇧", "BD": "🇧🇩", "BE": "🇧🇪", "BF": "🇧🇫", "BG": "🇧🇬", "BH": "🇧🇭", "BI": "🇧🇮", "BJ": "🇧🇯", "BL": "🇧🇱", "BM": "🇧🇲", "BN": "🇧🇳", "BO": "🇧🇴", "BQ": "🇧🇶", "BR": "🇧🇷", "BS": "🇧🇸", "BT": "🇧🇹", "BV": "🇧🇻", "BW": "🇧🇼", "BY": "🇧🇾", "BZ": "🇧🇿", "CA": "🇨🇦", "CC": "🇨🇨", "CD": "🇨🇩", "CF": "🇨🇫", "CG": "🇨🇬", "CH": "🇨🇭", "CI": "🇨🇮", "CK": "🇨🇰", "CL": "🇨🇱", "CM": "🇨🇲", "CN": "🇨🇳", "CO": "🇨🇴", "CR": "🇨🇷", "CU": "🇨🇺", "CV": "🇨🇻", "CW": "🇨🇼", "CX": "🇨🇽", "CY": "🇨🇾", "CZ": "🇨🇿", "DE": "🇩🇪", "DJ": "🇩🇯", "DK": "🇩🇰", "DM": "🇩🇲", "DO": "🇩🇴", "DZ": "🇩🇿", "EC": "🇪🇨", "EE": "🇪🇪", "EG": "🇪🇬", "EH": "🇪🇭", "ER": "🇪🇷", "ES": "🇪🇸", "ET": "🇪🇹", "FI": "🇫🇮", "FJ": "🇫🇯", "FK": "🇫🇰", "FM": "🇫🇲", "FO": "🇫🇴", "FR": "🇫🇷", "GA": "🇬🇦", "GB": "🇬🇧", "GD": "🇬🇩", "GE": "🇬🇪", "GF": "🇬🇫", "GG": "🇬🇬", "GH": "🇬🇭", "GI": "🇬🇮", "GL": "🇬🇱", "GM": "🇬🇲", "GN": "🇬🇳", "GP": "🇬🇵", "GQ": "🇬🇶", "GR": "🇬🇷", "GS": "🇬🇸", "GT": "🇬🇹", "GU": "🇬🇺", "GW": "🇬🇼", "GY": "🇬🇾", "HK": "🇭🇰", "HM": "🇭🇲", "HN": "🇭🇳", "HR": "🇭🇷", "HT": "🇭🇹", "HU": "🇭🇺", "ID": "🇮🇩", "IE": "🇮🇪", "IL": "🇮🇱", "IM": "🇮🇲", "IN": "🇮🇳", "IO": "🇮🇴", "IQ": "🇮🇶", "IR": "🇮🇷", "IS": "🇮🇸", "IT": "🇮🇹", "JE": "🇯🇪", "JM": "🇯🇲", "JO": "🇯🇴", "JP": "🇯🇵", "KE": "🇰🇪", "KG": "🇰🇬", "KH": "🇰🇭", "KI": "🇰🇮", "KM": "🇰🇲", "KN": "🇰🇳", "KP": "🇰🇵", "KR": "🇰🇷", "KW": "🇰🇼", "KY": "🇰🇾", "KZ": "🇰🇿", "LA": "🇱🇦", "LB": "🇱🇧", "LC": "🇱🇨", "LI": "🇱🇮", "LK": "🇱🇰", "LR": "🇱🇷", "LS": "🇱🇸", "LT": "🇱🇹", "LU": "🇱🇺", "LV": "🇱🇻", "LY": "🇱🇾", "MA": "🇲🇦", "MC": "🇲🇨", "MD": "🇲🇩", "ME": "🇲🇪", "MF": "🇲🇫", "MG": "🇲🇬", "MH": "🇲🇭", "MK": "🇲🇰", "ML": "🇲🇱", "MM": "🇲🇲", "MN": "🇲🇳", "MO": "🇲🇴", "MP": "🇲🇵", "MQ": "🇲🇶", "MR": "🇲🇷", "MS": "🇲🇸", "MT": "🇲🇹", "MU": "🇲🇺", "MV": "🇲🇻", "MW": "🇲🇼", "MX": "🇲🇽", "MY": "🇲🇾", "MZ": "🇲🇿", "NA": "🇳🇦", "NC": "🇳🇨", "NE": "🇳🇪", "NF": "🇳🇫", "NG": "🇳🇬", "NI": "🇳🇮", "NL": "🇳🇱", "NO": "🇳🇴", "NP": "🇳🇵", "NR": "🇳🇷", "NU": "🇳🇺", "NZ": "🇳🇿", "OM": "🇴🇲", "PA": "🇵🇦", "PE": "🇵🇪", "PF": "🇵🇫", "PG": "🇵🇬", "PH": "🇵🇭", "PK": "🇵🇰", "PL": "🇵🇱", "PM": "🇵🇲", "PN": "🇵🇳", "PR": "🇵🇷", "PS": "🇵🇸", "PT": "🇵🇹", "PW": "🇵🇼", "PY": "🇵🇾", "QA": "🇶🇦", "RE": "🇷🇪", "RO": "🇷🇴", "RS": "🇷🇸", "RU": "🇷🇺", "RW": "🇷🇼", "SA": "🇸🇦", "SB": "🇸🇧", "SC": "🇸🇨", "SD": "🇸🇩", "SE": "🇸🇪", "SG": "🇸🇬", "SH": "🇸🇭", "SI": "🇸🇮", "SJ": "🇸🇯", "SK": "🇸🇰", "SL": "🇸🇱", "SM": "🇸🇲", "SN": "🇸🇳", "SO": "🇸🇴", "SR": "🇸🇷", "SS": "🇸🇸", "ST": "🇸🇹", "SV": "🇸🇻", "SX": "🇸🇽", "SY": "🇸🇾", "SZ": "🇸🇿", "TC": "🇹🇨", "TD": "🇹🇩", "TF": "🇹🇫", "TG": "🇹🇬", "TH": "🇹🇭", "TJ": "🇹🇯", "TK": "🇹🇰", "TL": "🇹🇱", "TM": "🇹🇲", "TN": "🇹🇳", "TO": "🇹🇴", "TR": "🇹🇷", "TT": "🇹🇹", "TV": "🇹🇻", "TW": "🇹🇼", "TZ": "🇹🇿", "UA": "🇺🇦", "UG": "🇺🇬", "UM": "🇺🇲", "US": "🇺🇸", "UY": "🇺🇾", "UZ": "🇺🇿", "VA": "🇻🇦", "VC": "🇻🇨", "VE": "🇻🇪", "VG": "🇻🇬", "VI": "🇻🇮", "VN": "🇻🇳", "VU": "🇻🇺", "WF": "🇼🇫", "WS": "🇼🇸", "YE": "🇾🇪", "YT": "🇾🇹", "ZA": "🇿🇦", "ZM": "🇿🇲", "ZW": "🇿🇼" }
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AhoyPanel
4
- module HeroiconHelper
5
- include Heroicon::Engine.helpers
6
- end
7
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AhoyPanel
4
- module NavHelper
5
- def active_nav_link?(page_name)
6
- if controller_name == page_name
7
- "border-blue-500 text-gray-900"
8
- else
9
- "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700"
10
- end
11
- end
12
- end
13
- end
@@ -1,4 +0,0 @@
1
- import "@hotwired/turbo-rails"
2
- import "controllers"
3
- import "chartkick"
4
- import "Chart.bundle"
@@ -1,9 +0,0 @@
1
- import { Application } from "@hotwired/stimulus"
2
-
3
- const application = Application.start()
4
-
5
- // Configure Stimulus development experience
6
- application.debug = false
7
- window.Stimulus = application
8
-
9
- export { application }
@@ -1,11 +0,0 @@
1
- import { Controller } from '@hotwired/stimulus'
2
-
3
- export default class extends Controller {
4
- left(e) {
5
- Turbo.visit(e.target.dataset.url)
6
- }
7
-
8
- right(e) {
9
- Turbo.visit(e.target.dataset.url)
10
- }
11
- }
@@ -1,18 +0,0 @@
1
- import { Controller } from '@hotwired/stimulus'
2
- import { leave, toggle } from 'el-transition'
3
-
4
- export default class extends Controller {
5
- static targets = ['items']
6
-
7
- connect() {
8
- document.body.addEventListener('click', (e) => {
9
- if (!this.element.contains(e.target)) {
10
- leave(this.itemsTarget)
11
- }
12
- })
13
- }
14
-
15
- open() {
16
- toggle(this.itemsTarget)
17
- }
18
- }
@@ -1,11 +0,0 @@
1
- // Import and register all your controllers from the importmap under controllers/*
2
-
3
- import { application } from "controllers/application"
4
-
5
- // Eager load all controllers defined in the import map under controllers/**/*_controller
6
- import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
7
- eagerLoadControllersFrom("controllers", application)
8
-
9
- // Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
10
- // import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading"
11
- // lazyLoadControllersFrom("controllers", application)
@@ -1,20 +0,0 @@
1
- import { Controller } from '@hotwired/stimulus'
2
- import { enter, leave, toggle } from 'el-transition'
3
-
4
- export default class extends Controller {
5
- static targets = ['button', 'mobileMenu', 'closedIcon', 'openedIcon']
6
-
7
- toggle(e) {
8
- toggle(this.mobileMenuTarget);
9
-
10
- if (this.buttonTarget.dataset.open === 'false') {
11
- this.closedIconTarget.classList.add('hidden')
12
- this.openedIconTarget.classList.remove('hidden')
13
- this.buttonTarget.dataset.open = 'true'
14
- } else {
15
- this.closedIconTarget.classList.remove('hidden')
16
- this.openedIconTarget.classList.add('hidden')
17
- this.buttonTarget.dataset.open = 'false'
18
- }
19
- }
20
- }
@@ -1,4 +0,0 @@
1
- module AhoyPanel
2
- class BounceRateData < StatBoxData
3
- end
4
- end
@@ -1,26 +0,0 @@
1
- module AhoyPanel
2
- class StatBoxData
3
- def initialize(start_at:, end_at:)
4
- @start_at = start_at
5
- @end_at = end_at
6
- end
7
-
8
- attr_reader :start_at, :end_at
9
-
10
- def to_params
11
- { title:, data:, change: }
12
- end
13
-
14
- def title
15
- raise "Must implement"
16
- end
17
-
18
- def data
19
- raise "Must implement"
20
- end
21
-
22
- def change
23
- raise "Must implement"
24
- end
25
- end
26
- end
@@ -1,31 +0,0 @@
1
- module AhoyPanel
2
- class TotalPageviewsData < StatBoxData
3
- def title
4
- "Total Pageviews"
5
- end
6
-
7
- def data
8
- return @data if defined?(@data)
9
-
10
- @data ||= Ahoy::Visit.where(started_at: start_at..end_at).size
11
- end
12
-
13
- def change
14
- return @change if defined?(@change)
15
-
16
- start_back_at = if start_at.to_date == end_at.to_date
17
- start_back_days = 1
18
- else
19
- (end_at.to_date - start_at.to_date).to_i
20
- end
21
-
22
- start_range = (start_at - start_back_at.days)..(end_at - start_back_at.days)
23
- end_range = start_at..end_at
24
-
25
- start_count = Ahoy::Visit.where(started_at: start_range).size
26
- end_count = Ahoy::Visit.where(started_at: end_range).size
27
-
28
- @change = ((end_count - start_count).to_f / (start_count.zero? ? 1 : start_count) * 100).to_i
29
- end
30
- end
31
- end
@@ -1,29 +0,0 @@
1
- module AhoyPanel
2
- class TotalVisitsData < StatBoxData
3
- def title
4
- "Total Visits"
5
- end
6
-
7
- def data
8
- @data ||= Ahoy::Visit.where(started_at: start_at..end_at).size
9
- end
10
-
11
- def change
12
- return @change if defined?(@change)
13
-
14
- start_back_at = if start_at.to_date == end_at.to_date
15
- start_back_days = 1
16
- else
17
- (end_at.to_date - start_at.to_date).to_i
18
- end
19
-
20
- start_range = (start_at - start_back_at.days)..(end_at - start_back_at.days)
21
- end_range = start_at..end_at
22
-
23
- start_count = Ahoy::Visit.where(started_at: start_range).size
24
- end_count = Ahoy::Visit.where(started_at: end_range).size
25
-
26
- @change = ((end_count - start_count).to_f / (start_count.zero? ? 1 : start_count) * 100).to_i
27
- end
28
- end
29
- end
@@ -1,29 +0,0 @@
1
- module AhoyPanel
2
- class UniqueVisitorsData < StatBoxData
3
- def title
4
- "Unique Visitors"
5
- end
6
-
7
- def data
8
- @data ||= Ahoy::Visit.where(started_at: start_at..end_at).size
9
- end
10
-
11
- def change
12
- return @change if defined?(@change)
13
-
14
- start_back_at = if start_at.to_date == end_at.to_date
15
- start_back_days = 1
16
- else
17
- (end_at.to_date - start_at.to_date).to_i
18
- end
19
-
20
- start_range = (start_at - start_back_at.days)..(end_at - start_back_at.days)
21
- end_range = start_at..end_at
22
-
23
- start_count = Ahoy::Visit.where(started_at: start_range).size
24
- end_count = Ahoy::Visit.where(started_at: end_range).size
25
-
26
- @change = ((end_count - start_count).to_f / (start_count.zero? ? 1 : start_count) * 100).to_i
27
- end
28
- end
29
- end
@@ -1,4 +0,0 @@
1
- module AhoyPanel
2
- class ViewPerVisitData < StatBoxData
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module AhoyPanel
2
- class VisitDurationData < StatBoxData
3
- end
4
- end
@@ -1,77 +0,0 @@
1
- <div class="mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
2
- <div class="mb-8">
3
- <div class="flex justify-between items-center">
4
- <h3 class="text-base font-semibold text-gray-900">App Data</h3>
5
-
6
- <div class="flex items-center gap-x-4">
7
- <%= render AhoyPanel::DateArrowNavigatorComponent.new(date: @selected_date) %>
8
- <%= render AhoyPanel::DropdownComponent.new(item_groups: @dropdown_item_groups, date: @selected_date) %>
9
- </div>
10
- </div>
11
- <div class="overflow-hidden rounded-lg bg-white shadow mt-5">
12
- <div class="px-4">
13
- <dl class="mx-auto grid grid-cols-1 gap-px bg-gray-900/5 sm:grid-cols-2 lg:grid-cols-6">
14
- <%= render AhoyPanel::StatBoxComponent.new(**@unique_visitors_data.to_params) %>
15
- <%= render AhoyPanel::StatBoxComponent.new(**@total_visits_data.to_params) %>
16
- <%= render AhoyPanel::StatBoxComponent.new(**@total_pageviews_data.to_params) %>
17
- <%= render AhoyPanel::StatBoxComponent.new(title: "View Per Visit", data: 0, change: -1.39) %>
18
- <%= render AhoyPanel::StatBoxComponent.new(title: "Bounce Rate", data: 0, change: -1.39) %>
19
- <%= render AhoyPanel::StatBoxComponent.new(title: "Visit Duration", data: 0, change: -1.39) %>
20
- </dl>
21
-
22
- <!-- Content goes here -->
23
- <%= line_chart @visits.group_by_day(:started_at).count %>
24
- </div>
25
- </div>
26
- </div>
27
-
28
- <div class="mb-8 grid grid-cols-1 sm:grid-cols-2 gap-4">
29
- <div class="overflow-hidden rounded-lg bg-white shadow">
30
- <div class="px-4 py-5 sm:p-6">
31
- <p class="font-semibold text-gray-900 mb-5">Top Sources</p>
32
-
33
- <%= bar_chart @visits.group(:referring_domain).count.sort_by { |_, count| -count }.first(10).to_h, colors: ["#0284c7", "#4c7"] %>
34
-
35
- <div class="flex justify-center mt-6">
36
- <%= link_to "Details >", "", class: "link tracking-wide text-sm text-gray-600 font-semibold uppercase" %>
37
- </div>
38
- </div>
39
- </div>
40
-
41
- <div class="overflow-hidden rounded-lg bg-white shadow">
42
- <div class="px-4 py-5 sm:p-6">
43
- <p class="font-semibold text-gray-900 mb-5">Top Pages</p>
44
-
45
- <%= bar_chart @visits.group(:landing_page).count.sort_by { |_, count| -count }.first(10).to_h %>
46
-
47
- <div class="flex justify-center mt-6">
48
- <%= link_to "Details >", "", class: "link tracking-wide text-sm text-gray-600 font-semibold uppercase" %>
49
- </div>
50
- </div>
51
- </div>
52
-
53
- <div class="overflow-hidden rounded-lg bg-white shadow">
54
- <div class="px-4 py-5 sm:p-6">
55
- <p class="font-semibold text-gray-900 mb-5">Countries</p>
56
-
57
- <%= bar_chart @visits.where.not(country: nil).group(:country).count.sort_by { |_, count| -count }.first(10).to_h %>
58
-
59
- <div class="flex justify-center mt-6">
60
- <%= link_to "Details >", "", class: "link tracking-wide text-sm text-gray-600 font-semibold uppercase" %>
61
- </div>
62
- </div>
63
- </div>
64
-
65
- <div class="overflow-hidden rounded-lg bg-white shadow">
66
- <div class="px-4 py-5 sm:p-6">
67
- <p class="font-semibold text-gray-900 mb-5">Browsers</p>
68
-
69
- <%= bar_chart @visits.where.not(browser: nil).group(:browser).count.sort_by { |_, count| -count }.first(10).to_h %>
70
-
71
- <div class="flex justify-center mt-6">
72
- <%= link_to "Details >", "", class: "link tracking-wide text-sm text-gray-600 font-semibold uppercase" %>
73
- </div>
74
- </div>
75
- </div>
76
- </div>
77
- </div>
@@ -1,82 +0,0 @@
1
- <nav
2
- data-controller="header mobile-header"
3
- class="bg-white shadow"
4
- >
5
- <div class="mx-auto max-w-7xl px-2 sm:px-4 lg:px-8">
6
- <div class="flex h-16 justify-between">
7
- <div class="flex px-2 lg:px-0">
8
- <div class="flex shrink-0 items-center">
9
- <img class="h-8 w-auto" src="https://tailwindui.com/plus/img/logos/mark.svg?color=sky&shade=600" alt="Your Company">
10
- </div>
11
- <div class="hidden lg:ml-6 lg:flex lg:space-x-8">
12
- <!-- Current: "border-sky-500 text-gray-900", Default: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700" -->
13
- <a href="#" class="inline-flex items-center border-b-2 border-sky-500 px-1 pt-1 text-sm font-medium text-gray-900">Dashboard</a>
14
- <% if false %>
15
- <a href="#" class="inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700">Boards</a>
16
- <% end %>
17
- </div>
18
- </div>
19
- <div class="flex items-center lg:hidden">
20
- <!-- Mobile menu button -->
21
- <button
22
- data-action="click->mobile-header#toggle"
23
- data-mobile-header-target="button"
24
- data-open="false"
25
- type="button"
26
- class="relative inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-100 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-sky-500" aria-controls="mobile-menu" aria-expanded="false"
27
- >
28
- <span class="absolute -inset-0.5"></span>
29
- <span class="sr-only">Open main menu</span>
30
- <!--
31
- Icon when menu is closed.
32
-
33
- Menu open: "hidden", Menu closed: "block"
34
- -->
35
- <svg
36
- data-mobile-header-target="closedIcon"
37
- class="block size-6"
38
- fill="none"
39
- viewBox="0 0 24 24"
40
- stroke-width="1.5"
41
- stroke="currentColor"
42
- aria-hidden="true"
43
- data-slot="icon"
44
- >
45
- <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
46
- </svg>
47
- <!--
48
- Icon when menu is open.
49
-
50
- Menu open: "block", Menu closed: "hidden"
51
- -->
52
- <svg
53
- data-mobile-header-target="openedIcon"
54
- class="hidden size-6"
55
- fill="none"
56
- viewBox="0 0 24 24"
57
- stroke-width="1.5"
58
- stroke="currentColor"
59
- aria-hidden="true"
60
- data-slot="icon"
61
- >
62
- <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
63
- </svg>
64
- </button>
65
- </div>
66
- </div>
67
- </div>
68
-
69
- <!-- Mobile menu, show/hide based on menu state. -->
70
- <div
71
- data-mobile-header-target="mobileMenu"
72
- class="hidden"
73
- >
74
- <div class="space-y-1 pb-3 pt-2">
75
- <!-- Current: "bg-sky-50 border-sky-500 text-sky-700", Default: "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800" -->
76
- <a href="#" class="block border-l-4 border-sky-500 bg-sky-50 py-2 pl-3 pr-4 text-base font-medium text-sky-700">Dashboard</a>
77
- <% if false %>
78
- <a href="#" class="block border-l-4 border-transparent py-2 pl-3 pr-4 text-base font-medium text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800">Boards</a>
79
- <% end %>
80
- </div>
81
- </div>
82
- </nav>
data/config/importmap.rb DELETED
@@ -1,8 +0,0 @@
1
- pin "application-ahoy-panel", to: "ahoy_panel/application.js", preload: true
2
- pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
3
- pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
4
- pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
5
- pin_all_from AhoyPanel::Engine.root.join("app/javascript/ahoy_panel/controllers"), under: "controllers", to: "ahoy_panel/controllers"
6
- pin "el-transition" # @0.0.7
7
- pin "chartkick", to: "chartkick.js"
8
- pin "Chart.bundle", to: "Chart.bundle.js"
@@ -1,10 +0,0 @@
1
- require "heroicon"
2
-
3
- Heroicon.configure do |config|
4
- config.variant = :solid # Options are :solid, :outline and :mini
5
-
6
- ##
7
- # You can set a default class, which will get applied to every icon with
8
- # the given variant. To do so, un-comment the line below.
9
- # config.default_class = {solid: "h-5 w-5", outline: "h-6 w-6", mini: "h-4 w-4"}
10
- end
@@ -1,5 +0,0 @@
1
- require "inline_svg"
2
-
3
- InlineSvg.configure do |config|
4
- config.asset_finder = InlineSvg::PropshaftAssetFinder
5
- end
@@ -1,23 +0,0 @@
1
- const defaultTheme = require('tailwindcss/defaultTheme')
2
-
3
- module.exports = {
4
- content: [
5
- './public/*.html',
6
- './app/helpers/**/*.rb',
7
- './app/javascript/**/*.js',
8
- './app/views/**/*.{erb,haml,html,slim}',
9
- './app/components/**/*.{erb,haml,html,slim}'
10
- ],
11
- theme: {
12
- extend: {
13
- fontFamily: {
14
- sans: ['Inter var', ...defaultTheme.fontFamily.sans],
15
- },
16
- },
17
- },
18
- plugins: [
19
- require('@tailwindcss/forms'),
20
- require('@tailwindcss/typography'),
21
- require('@tailwindcss/container-queries'),
22
- ]
23
- }