ahoy_panel 0.0.1

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 (48) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +63 -0
  4. data/Rakefile +8 -0
  5. data/app/assets/builds/ahoy_panel.css +1 -0
  6. data/app/assets/config/ahoy_panel_manifest.js +3 -0
  7. data/app/assets/stylesheets/ahoy_panel/application.tailwind.css +13 -0
  8. data/app/components/ahoy_panel/date_arrow_navigator_component.html.erb +38 -0
  9. data/app/components/ahoy_panel/date_arrow_navigator_component.rb +12 -0
  10. data/app/components/ahoy_panel/dropdown_component.html.erb +53 -0
  11. data/app/components/ahoy_panel/dropdown_component.rb +35 -0
  12. data/app/components/ahoy_panel/stat_box_component.html.erb +22 -0
  13. data/app/components/ahoy_panel/stat_box_component.rb +13 -0
  14. data/app/controllers/ahoy_panel/application_controller.rb +4 -0
  15. data/app/controllers/ahoy_panel/dashboard_controller.rb +69 -0
  16. data/app/helpers/ahoy_panel/application_helper.rb +4 -0
  17. data/app/helpers/ahoy_panel/country_helper.rb +7 -0
  18. data/app/helpers/ahoy_panel/heroicon_helper.rb +7 -0
  19. data/app/helpers/ahoy_panel/nav_helper.rb +13 -0
  20. data/app/javascript/ahoy_panel/application.js +4 -0
  21. data/app/javascript/ahoy_panel/controllers/application.js +9 -0
  22. data/app/javascript/ahoy_panel/controllers/date_arrow_navigator_controller.js +11 -0
  23. data/app/javascript/ahoy_panel/controllers/dropdown_controller.js +18 -0
  24. data/app/javascript/ahoy_panel/controllers/index.js +11 -0
  25. data/app/javascript/ahoy_panel/controllers/mobile_header_controller.js +20 -0
  26. data/app/jobs/ahoy_panel/application_job.rb +4 -0
  27. data/app/mailers/ahoy_panel/application_mailer.rb +6 -0
  28. data/app/models/ahoy_panel/application_record.rb +5 -0
  29. data/app/models/ahoy_panel/bounce_rate_data.rb +4 -0
  30. data/app/models/ahoy_panel/stat_box_data.rb +26 -0
  31. data/app/models/ahoy_panel/total_pageviews_data.rb +31 -0
  32. data/app/models/ahoy_panel/total_visits_data.rb +29 -0
  33. data/app/models/ahoy_panel/unique_visitors_data.rb +29 -0
  34. data/app/models/ahoy_panel/view_per_visit_data.rb +4 -0
  35. data/app/models/ahoy_panel/visit_duration_data.rb +4 -0
  36. data/app/views/ahoy_panel/dashboard/index.html.erb +77 -0
  37. data/app/views/layouts/ahoy_panel/_header.html.erb +82 -0
  38. data/app/views/layouts/ahoy_panel/application.html.erb +19 -0
  39. data/config/importmap.rb +8 -0
  40. data/config/initializers/heroicon.rb +10 -0
  41. data/config/initializers/inline_svg.rb +5 -0
  42. data/config/routes.rb +3 -0
  43. data/config/tailwind.config.js +23 -0
  44. data/lib/ahoy_panel/engine.rb +19 -0
  45. data/lib/ahoy_panel/version.rb +3 -0
  46. data/lib/ahoy_panel.rb +6 -0
  47. data/lib/tasks/ahoy_panel_tasks.rake +19 -0
  48. metadata +243 -0
@@ -0,0 +1,29 @@
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
@@ -0,0 +1,29 @@
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
@@ -0,0 +1,4 @@
1
+ module AhoyPanel
2
+ class ViewPerVisitData < StatBoxData
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module AhoyPanel
2
+ class VisitDurationData < StatBoxData
3
+ end
4
+ end
@@ -0,0 +1,77 @@
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>
@@ -0,0 +1,82 @@
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>
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>AhoyPanel</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
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" %>
11
+
12
+ <%= yield :head %>
13
+ </head>
14
+
15
+ <body class="bg-gray-100 h-full">
16
+ <%= render "layouts/ahoy_panel/header" %>
17
+ <%= yield %>
18
+ </body>
19
+ </html>
@@ -0,0 +1,8 @@
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"
@@ -0,0 +1,10 @@
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
@@ -0,0 +1,5 @@
1
+ require "inline_svg"
2
+
3
+ InlineSvg.configure do |config|
4
+ config.asset_finder = InlineSvg::PropshaftAssetFinder
5
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ AhoyPanel::Engine.routes.draw do
2
+ root to: "dashboard#index"
3
+ end
@@ -0,0 +1,23 @@
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
+ }
@@ -0,0 +1,19 @@
1
+ require "importmap-rails"
2
+ require "turbo-rails"
3
+ require "stimulus-rails"
4
+
5
+ module AhoyPanel
6
+ class Engine < ::Rails::Engine
7
+ isolate_namespace AhoyPanel
8
+
9
+ initializer "ahoy_panel.assets" do |app|
10
+ app.config.assets.paths << root.join("app/javascript")
11
+ app.config.assets.precompile += %w[ahoy_panel_manifest]
12
+ end
13
+
14
+ initializer "ahoy_panel.importmap", before: "importmap" do |app|
15
+ app.config.importmap.paths << root.join("config/importmap.rb")
16
+ app.config.importmap.cache_sweepers << root.join("app/javascript")
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module AhoyPanel
2
+ VERSION = "0.0.1"
3
+ end
data/lib/ahoy_panel.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "ahoy_panel/version"
2
+ require "ahoy_panel/engine"
3
+
4
+ module AhoyPanel
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,19 @@
1
+ # desc "Explaining what the task does"
2
+ # task :ahoy_panel do
3
+ # # Task goes here
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 ADDED
@@ -0,0 +1,243 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ahoy_panel
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Jeon
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-02-08 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: tailwindcss-rails
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 3.3.1
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
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
166
+ description: Ahoy is a great analytics tracking gem. AhoyPanel is a great dashboard
167
+ for the data collected by Ahoy
168
+ email:
169
+ - chris@typefast.co
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files: []
173
+ files:
174
+ - MIT-LICENSE
175
+ - README.md
176
+ - 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
186
+ - app/controllers/ahoy_panel/application_controller.rb
187
+ - app/controllers/ahoy_panel/dashboard_controller.rb
188
+ - 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
+ - app/jobs/ahoy_panel/application_job.rb
199
+ - app/mailers/ahoy_panel/application_mailer.rb
200
+ - 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
+ - app/views/layouts/ahoy_panel/application.html.erb
211
+ - config/importmap.rb
212
+ - config/initializers/heroicon.rb
213
+ - config/initializers/inline_svg.rb
214
+ - config/routes.rb
215
+ - config/tailwind.config.js
216
+ - lib/ahoy_panel.rb
217
+ - lib/ahoy_panel/engine.rb
218
+ - lib/ahoy_panel/version.rb
219
+ - lib/tasks/ahoy_panel_tasks.rake
220
+ homepage: https://www.ahoypanel.com
221
+ licenses:
222
+ - MIT
223
+ metadata:
224
+ homepage_uri: https://www.ahoypanel.com
225
+ source_code_uri: https://github.com/typefastco/ahoy_panel.
226
+ rdoc_options: []
227
+ require_paths:
228
+ - lib
229
+ required_ruby_version: !ruby/object:Gem::Requirement
230
+ requirements:
231
+ - - ">="
232
+ - !ruby/object:Gem::Version
233
+ version: '0'
234
+ required_rubygems_version: !ruby/object:Gem::Requirement
235
+ requirements:
236
+ - - ">="
237
+ - !ruby/object:Gem::Version
238
+ version: '0'
239
+ requirements: []
240
+ rubygems_version: 3.6.2
241
+ specification_version: 4
242
+ summary: Interactive dashboard panel for Ahoy analytics for Rails apps.
243
+ test_files: []