diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb index ff37a608..e80eb20b 100644 --- a/app/controllers/documents_controller.rb +++ b/app/controllers/documents_controller.rb @@ -25,6 +25,7 @@ class DocumentsController < ApplicationController @recent_documents = current_user .linkable_documents.order('updated_at DESC') .includes([:user, :page_tags, :universe]) + .limit(10) # Limit for sidebar display @documents = current_user .linkable_documents @@ -36,6 +37,34 @@ class DocumentsController < ApplicationController .where(context: 'Document', parent_folder_id: nil) .order('title ASC') + # Calculate frequent folders (top 5 by document count) + @frequent_folders = current_user + .folders + .where(context: 'Document') + .joins(:documents) + .group('folders.id') + .order('COUNT(documents.id) DESC') + .limit(5) + + # Writing statistics + @total_documents = current_user.linkable_documents.count + @total_word_count = current_user.linkable_documents.sum(:cached_word_count) || 0 + @average_words_per_doc = @total_documents > 0 ? (@total_word_count.to_f / @total_documents).round : 0 + + # This month's stats + @documents_this_month = current_user.linkable_documents + .where('created_at >= ?', Date.current.beginning_of_month) + .count + + # Calculate writing streak using WordCountUpdate + calculate_writing_streak_data + + # Recent activity for feed + @recent_activity = current_user.linkable_documents + .order('updated_at DESC') + .limit(10) + .select(:id, :title, :updated_at, :cached_word_count, :user_id) + # TODO: can we reuse this content to skip a few queries in this controller action? cache_linkable_content_for_each_content_type @@ -307,6 +336,40 @@ class DocumentsController < ApplicationController private + def calculate_writing_streak_data + # Get last 30 days of word count updates + @writing_activity = {} + 30.downto(0) do |days_ago| + date = Date.current - days_ago + @writing_activity[date] = WordCountUpdate + .where(user: current_user, for_date: date) + .sum(:word_count) + end + + # Calculate current streak + @current_streak = 0 + Date.current.downto(Date.current - 365) do |date| + if WordCountUpdate.where(user: current_user, for_date: date).exists? + @current_streak += 1 + else + break + end + end + + # Calculate longest streak (simplified version for now) + @longest_streak = @current_streak # This would need more complex calculation + + # Today's word count + @words_written_today = WordCountUpdate + .where(user: current_user, for_date: Date.current) + .sum(:word_count) + + # This week's word count + @words_written_this_week = WordCountUpdate + .where(user: current_user, for_date: Date.current.beginning_of_week..Date.current) + .sum(:word_count) + end + def update_page_tags(document) tag_list = document_tag_params.fetch('value', '').split(PageTag::SUBMISSION_DELIMITER) current_tags = document.page_tags.pluck(:tag) diff --git a/app/views/documents/index.html.erb b/app/views/documents/index.html.erb index c96ffb88..f46d683c 100644 --- a/app/views/documents/index.html.erb +++ b/app/views/documents/index.html.erb @@ -1,585 +1,532 @@
- -
-
-
-

Documents

-
- <%= link_to new_document_path, class: "inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" do %> - add - New Document - <% end %> -
- +
+ + +
+
+ + search +
+
+ + +
+ <%= link_to new_document_path, class: "w-full inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-lg shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" do %> + add + New Document + <% end %> + +
+ + +
+

+ history + Recently Edited +

+ <% if @recent_documents.any? %> +
+ <% @recent_documents.first(7).each do |document| %> + <%= link_to edit_document_path(document), class: "block group" do %> +
+
+
+

+ <%= document.title %> +

+
+ <%= number_with_delimiter(document.cached_word_count || 0) %> words + + <%= time_ago_in_words(document.updated_at) %> ago +
+
+ <% + time_diff = Time.current - document.updated_at + recency_class = case + when time_diff < 1.hour then "bg-red-500 animate-pulse" + when time_diff < 6.hours then "bg-orange-500" + when time_diff < 24.hours then "bg-yellow-500" + else "bg-gray-400" + end + %> +
+
+
+ <% end %> + <% end %> +
+ <% else %> +

No recent documents

+ <% end %> +
+ + +
+

+ folder_special + Frequent Folders +

+ <% if @frequent_folders.any? %> +
+ <% @frequent_folders.each do |folder| %> + <%= link_to folder_path(folder), class: "block group" do %> +
+ folder +
+

+ <%= folder.title %> +

+
+ + <%= folder.documents.count %> docs + +
+ <% end %> + <% end %> +
+ <% else %> +

No folders yet

+ <% end %> +
+ + + +
+ +
+
+
+
+ + +

Documents Library

+
+ + + - +
+ + +
+
+ +
+ + search +
+ +
+ +
+ + +
+ + +
+ + +
+
+
+ + +
+
+ description + <%= @total_documents %> documents +
+
+ folder + <%= @folders.count %> folders
-
-
- - -
-
-
- description - <%= Document.where(user_id: current_user.id).count %> documents -
-
- folder - <%= @folders.count %> folders -
-
- text_fields - <%= number_with_delimiter(Document.where(user_id: current_user.id).sum(:cached_word_count) || 0) %> words -
- <% recent_doc = Document.where(user_id: current_user.id).order(updated_at: :desc).first %> - <% if recent_doc.present? %> -
- update - Last updated <%= time_ago_in_words(recent_doc.updated_at) %> ago -
- <% end %> -
-
- - -
-
-

Recently Edited

-
- - <% if @recent_documents.any? %> -
-
- <% @recent_documents.each do |document| %> - <%= link_to edit_document_path(document), class: "flex-shrink-0 group" do %> -
- -
- -
- <%= image_tag "card-headers/documents.webp", class: 'object-cover object-center w-full h-full opacity-80' %> - -
-
- - -
-
-

<%= document.title %>

-
- <%= number_with_delimiter(document.cached_word_count || 0) %> words -
-
-
-
- <% if document.folder %> - - folder - <%= document.folder.title %> - - <% else %> - No folder - <% end %> -
-
-
- - -
-
- - -
- <%= time_ago_in_words(document.updated_at) %> ago -
-
- <% end %> - <% end %> -
-
- <% else %> -
- No recently edited documents -
- <% end %> -
- - - - - - -
-
-
-

Library

-
-
- - -
-
-
-
- -
- - -
- - - -
-
- - <% if @folders.any? || Document.where(user_id: current_user.id).any? %> -
- - <% if @folders.any? %> -
-

Folders

-
- <% @folders.each do |folder| %> - <%= link_to folder_path(folder), class: "block group" do %> -
- -
- -
- - -
-
-
- -
- <%= Folder.icon %> -
- - -
-

<%= folder.title %>

-
- <% if folder.documents.count > 0 %> - description - <%= folder.documents.count %> <%= folder.documents.count == 1 ? 'doc' : 'docs' %> - <% else %> - folder_open - Empty - <% end %> + + +
+ <% if @folders.any? || @documents.any? %> + +
+ + <% if @folders.any? %> +
+

Folders

+
+ <% @folders.each do |folder| %> + <%= link_to folder_path(folder), class: "block group" do %> +
+
+
+
+
+
+
+ <%= Folder.icon %> +
+
+

<%= folder.title %>

+
+ <% if folder.documents.count > 0 %> + description + <%= folder.documents.count %> <%= folder.documents.count == 1 ? 'doc' : 'docs' %> + <% else %> + folder_open + Empty + <% end %> +
+
- - -
-
-
-
-
- <% end %> - <% end %> -
-
- <% end %> - - - <% if Document.where(user_id: current_user.id).any? %> -
-

Documents

-
- <% Document.where(user_id: current_user.id).order(updated_at: :desc).each do |document| %> -
- <%= link_to edit_document_path(document), class: "block" do %> - -
- <%= image_tag "card-headers/documents.webp", class: 'object-cover object-center w-full h-full' %> - - - <% - time_diff = Time.current - document.updated_at - recency_class = case - when time_diff < 1.hour then "bg-red-500 animate-pulse" - when time_diff < 6.hours then "bg-orange-500" - when time_diff < 24.hours then "bg-yellow-500" - else "bg-gray-400" - end - %> -
- - -
-
-
-

- <%= document.title %> -

+ <% end %> + <% end %> +
+
+ <% end %> + + + <% if @documents.any? %> +
+

Documents

+
+ <% @documents.each do |document| %> +
+ <%= link_to edit_document_path(document), class: "block" do %> + +
+ <%= image_tag "card-headers/documents.webp", class: 'object-cover object-center w-full h-full' %> + + + <% + time_diff = Time.current - document.updated_at + recency_class = case + when time_diff < 1.hour then "bg-red-500 animate-pulse" + when time_diff < 6.hours then "bg-orange-500" + when time_diff < 24.hours then "bg-yellow-500" + else "bg-gray-400" + end + %> +
+ + +
+
+
+

+ <%= document.title %> +

+
+
-
-
- - -
-
- <% if document.folder %> - - folder - <%= document.folder.title %> + + +
+
+ <% if document.folder %> + + folder + <%= document.folder.title %> + + <% end %> + + description + <%= number_with_delimiter(document.cached_word_count || 0) %> words + +
+ + <%= time_ago_in_words(document.updated_at) %> ago - <% end %> - - description - <%= number_with_delimiter(document.cached_word_count || 0) %> words - -
- - <%= time_ago_in_words(document.updated_at) %> ago - -
- - -
- <%= link_to edit_document_path(document), class: "p-1.5 bg-white/90 text-gray-700 hover:bg-white rounded-lg shadow-sm backdrop-blur-sm", title: "Edit", onclick: "event.stopPropagation();" do %> - edit - <% end %> - <%= link_to document_path(document), class: "p-1.5 bg-white/90 text-gray-700 hover:bg-white rounded-lg shadow-sm backdrop-blur-sm", title: "View", onclick: "event.stopPropagation();" do %> - open_in_new +
<% end %>
<% end %>
- <% end %> +
+ <% end %> +
+ + + + <% else %> + +
+
+
+ folder_open +
+

Welcome to your Library

+

Start organizing your work by creating folders and documents.

+
+ + <%= link_to new_document_path, class: "inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700" do %> + add + Create Document + <% end %> +
<% end %>
+ + + +
- -
-
-

Document Templates

- View all templates -
- -
- -
-
-
- description -
-
-

Blank Document

-

Start with a clean slate

-
-
-
-
- <%= link_to new_document_path, class: "font-medium text-blue-600 hover:text-blue-800" do %> - Use template - <% end %> -
-
-
- - -
-
-
- book -
-
-

Chapter

-

Novel or book chapter template

-
-
-
-
- <%= link_to new_document_path(template: 'chapter'), class: "font-medium text-blue-600 hover:text-blue-800" do %> - Use template - <% end %> -
-
-
- - -
-
-
- science -
-
-

Research Notes

-

Structured research template

-
-
-
-
- <%= link_to new_document_path(template: 'research'), class: "font-medium text-blue-600 hover:text-blue-800" do %> - Use template - <% end %> -
-
-
- - -
-
-
- mail -
-
-

Letter

-

Formal letter template

-
-
-
-
- <%= link_to new_document_path(template: 'letter'), class: "font-medium text-blue-600 hover:text-blue-800" do %> - Use template - <% end %> -
-
-
-
+ + - - -
\ No newline at end of file +
+ + \ No newline at end of file diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 6cbebaa2..8642d396 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -284,7 +284,7 @@