ahoy_panel 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/.rspec +3 -0
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +21 -41
- data/Rakefile +9 -5
- data/lib/ahoy_panel/version.rb +3 -1
- data/lib/ahoy_panel.rb +4 -2
- data/sig/ahoy_panel.rbs +4 -0
- metadata +13 -189
- data/MIT-LICENSE +0 -20
- data/app/assets/builds/ahoy_panel.css +0 -1
- data/app/assets/config/ahoy_panel_manifest.js +0 -3
- data/app/assets/stylesheets/ahoy_panel/application.tailwind.css +0 -13
- data/app/components/ahoy_panel/date_arrow_navigator_component.html.erb +0 -38
- data/app/components/ahoy_panel/date_arrow_navigator_component.rb +0 -12
- data/app/components/ahoy_panel/dropdown_component.html.erb +0 -53
- data/app/components/ahoy_panel/dropdown_component.rb +0 -35
- data/app/components/ahoy_panel/stat_box_component.html.erb +0 -22
- data/app/components/ahoy_panel/stat_box_component.rb +0 -13
- data/app/controllers/ahoy_panel/application_controller.rb +0 -4
- data/app/controllers/ahoy_panel/dashboard_controller.rb +0 -69
- data/app/helpers/ahoy_panel/application_helper.rb +0 -4
- data/app/helpers/ahoy_panel/country_helper.rb +0 -7
- data/app/helpers/ahoy_panel/heroicon_helper.rb +0 -7
- data/app/helpers/ahoy_panel/nav_helper.rb +0 -13
- data/app/javascript/ahoy_panel/application.js +0 -4
- data/app/javascript/ahoy_panel/controllers/application.js +0 -9
- data/app/javascript/ahoy_panel/controllers/date_arrow_navigator_controller.js +0 -11
- data/app/javascript/ahoy_panel/controllers/dropdown_controller.js +0 -18
- data/app/javascript/ahoy_panel/controllers/index.js +0 -11
- data/app/javascript/ahoy_panel/controllers/mobile_header_controller.js +0 -20
- data/app/jobs/ahoy_panel/application_job.rb +0 -4
- data/app/mailers/ahoy_panel/application_mailer.rb +0 -6
- data/app/models/ahoy_panel/application_record.rb +0 -5
- data/app/models/ahoy_panel/bounce_rate_data.rb +0 -4
- data/app/models/ahoy_panel/stat_box_data.rb +0 -26
- data/app/models/ahoy_panel/total_pageviews_data.rb +0 -31
- data/app/models/ahoy_panel/total_visits_data.rb +0 -29
- data/app/models/ahoy_panel/unique_visitors_data.rb +0 -29
- data/app/models/ahoy_panel/view_per_visit_data.rb +0 -4
- data/app/models/ahoy_panel/visit_duration_data.rb +0 -4
- data/app/views/ahoy_panel/dashboard/index.html.erb +0 -77
- data/app/views/layouts/ahoy_panel/_header.html.erb +0 -82
- data/app/views/layouts/ahoy_panel/application.html.erb +0 -19
- data/config/importmap.rb +0 -8
- data/config/initializers/heroicon.rb +0 -10
- data/config/initializers/inline_svg.rb +0 -5
- data/config/routes.rb +0 -3
- data/config/tailwind.config.js +0 -23
- data/lib/ahoy_panel/engine.rb +0 -20
- data/lib/tasks/ahoy_panel_tasks.rake +0 -19
@@ -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,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,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,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,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,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>
|