diff --git a/README.md b/README.md index 2cd19ea..7b722e1 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,48 @@ Check out a live demo at [linkarooie.com](https://linkarooie.com). 5. Visit `http://localhost:3000` in your browser. +#### Analytics Temporary + +I have added analytics but not a dashboard to view them yet. This is how it works so far. + +- Open the Rails console `rails console` + +```ruby +puts "Page Views for loftwah:" +user = User.find_by(username: 'loftwah') +puts user.page_views.count + +puts "\nMost recent Page Views with new data:" +puts PageView.order(created_at: :desc).limit(5).map { |pv| "#{pv.path} - #{pv.created_at} - IP: #{pv.ip_address} - Session: #{pv.session_id}" } + +puts "\nLink Clicks for loftwah's links:" +puts user.links.sum { |link| link.link_clicks.count } + +puts "\nMost recent Link Clicks with new data:" +puts LinkClick.order(created_at: :desc).limit(5).map { |lc| "#{lc.link.title} - #{lc.created_at} - IP: #{lc.ip_address} - Session: #{lc.session_id}" } + +puts "\nMost viewed pages:" +puts PageView.group(:path).order('count_id DESC').limit(5).count(:id) + +puts "\nMost clicked links:" +puts LinkClick.joins(:link).group('links.title').order('count_id DESC').limit(5).count(:id) + +puts "\nTotal tracking counts:" +puts "Page Views: #{PageView.count}" +puts "Link Clicks: #{LinkClick.count}" +puts "Achievement Views: #{AchievementView.count}" + +puts "\nUnique IP addresses:" +puts "Page Views: #{PageView.distinct.count(:ip_address)}" +puts "Link Clicks: #{LinkClick.distinct.count(:ip_address)}" +puts "Achievement Views: #{AchievementView.distinct.count(:ip_address)}" + +puts "\nUnique sessions:" +puts "Page Views: #{PageView.distinct.count(:session_id)}" +puts "Link Clicks: #{LinkClick.distinct.count(:session_id)}" +puts "Achievement Views: #{AchievementView.distinct.count(:session_id)}" +``` + ### Docker Deployment 1. Build and start the Docker containers: diff --git a/app/controllers/achievements_controller.rb b/app/controllers/achievements_controller.rb index 35e1a85..f5ba036 100644 --- a/app/controllers/achievements_controller.rb +++ b/app/controllers/achievements_controller.rb @@ -7,6 +7,21 @@ def index def show @achievement = Achievement.find(params[:id]) + AchievementView.create( + achievement: @achievement, + user: @achievement.user, + viewed_at: Time.current, + referrer: request.referrer, + browser: request.user_agent, + ip_address: request.ip, + session_id: request.session.id + ) + + if @achievement.url.present? + redirect_to @achievement.url, allow_other_host: true + else + render :show + end end def new @@ -46,4 +61,4 @@ def destroy def achievement_params params.require(:achievement).permit(:title, :date, :description, :icon, :url) end -end +end \ No newline at end of file diff --git a/app/controllers/links_controller.rb b/app/controllers/links_controller.rb index 863c8b1..170d915 100644 --- a/app/controllers/links_controller.rb +++ b/app/controllers/links_controller.rb @@ -49,9 +49,23 @@ def user_links @user.tags = JSON.parse(@user.tags) if @user.tags.is_a?(String) end + def track_click + @link = Link.find(params[:id]) + LinkClick.create( + link: @link, + user: @link.user, + clicked_at: Time.current, + referrer: request.referrer, + browser: request.user_agent, + ip_address: request.ip, + session_id: request.session.id + ) + redirect_to @link.url, allow_other_host: true + end + private def link_params params.require(:link).permit(:url, :title, :description, :position, :icon, :visible, :pinned) end -end +end \ No newline at end of file diff --git a/app/middleware/page_view_tracker.rb b/app/middleware/page_view_tracker.rb new file mode 100644 index 0000000..4ca38b1 --- /dev/null +++ b/app/middleware/page_view_tracker.rb @@ -0,0 +1,35 @@ +class PageViewTracker + def initialize(app) + @app = app + end + + def call(env) + request = ActionDispatch::Request.new(env) + status, headers, response = @app.call(env) + + if html_response?(headers) && !request.path.start_with?('/assets', '/rails/active_storage') + track_page_view(request) + end + + [status, headers, response] + end + + private + + def html_response?(headers) + headers['Content-Type']&.include?('text/html') + end + + def track_page_view(request) + user = User.find_by(username: request.path.split('/').last) + PageView.create( + user: user, + path: request.path, + referrer: request.referrer, + browser: request.user_agent, + visited_at: Time.current, + ip_address: request.ip, + session_id: request.session[:session_id] + ) if user + end +end \ No newline at end of file diff --git a/app/models/achievement.rb b/app/models/achievement.rb index cd70053..88e5a91 100644 --- a/app/models/achievement.rb +++ b/app/models/achievement.rb @@ -1,6 +1,8 @@ class Achievement < ApplicationRecord belongs_to :user + has_many :achievement_views + validates :title, presence: true validates :date, presence: true validates :description, presence: true diff --git a/app/models/achievement_view.rb b/app/models/achievement_view.rb new file mode 100644 index 0000000..4876677 --- /dev/null +++ b/app/models/achievement_view.rb @@ -0,0 +1,4 @@ +class AchievementView < ApplicationRecord + belongs_to :achievement + belongs_to :user +end diff --git a/app/models/link.rb b/app/models/link.rb index a3ffaca..5191d76 100644 --- a/app/models/link.rb +++ b/app/models/link.rb @@ -1,5 +1,7 @@ class Link < ApplicationRecord belongs_to :user + + has_many :link_clicks scope :visible, -> { where(visible: true) } scope :pinned, -> { where(pinned: true) } diff --git a/app/models/link_click.rb b/app/models/link_click.rb new file mode 100644 index 0000000..b53dadf --- /dev/null +++ b/app/models/link_click.rb @@ -0,0 +1,4 @@ +class LinkClick < ApplicationRecord + belongs_to :link + belongs_to :user +end diff --git a/app/models/page_view.rb b/app/models/page_view.rb new file mode 100644 index 0000000..34cc654 --- /dev/null +++ b/app/models/page_view.rb @@ -0,0 +1,3 @@ +class PageView < ApplicationRecord + belongs_to :user +end diff --git a/app/models/user.rb b/app/models/user.rb index 9b373e1..b896b01 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,6 +5,10 @@ class User < ApplicationRecord has_many :links, dependent: :destroy has_many :achievements, dependent: :destroy + has_many :page_views + has_many :link_clicks + has_many :achievement_views + validates :username, presence: true, uniqueness: true validates :full_name, presence: true diff --git a/app/views/links/user_links.html.erb b/app/views/links/user_links.html.erb index 4ab2761..1ebebca 100644 --- a/app/views/links/user_links.html.erb +++ b/app/views/links/user_links.html.erb @@ -26,7 +26,7 @@