Files
TimeTracker/app/templates/main/help.html
Dries Peeters 18d9808d5e feat: add user favorite projects functionality with CSV export enhancements
Features:
Add favorite projects feature allowing users to star/bookmark frequently used projects
New UserFavoriteProject association model with user-project relationships
Star icons in project list for one-click favorite toggling via AJAX
Filter to display only favorite projects
Per-user favorites with proper isolation and cascade delete behavior
Activity logging for favorite/unfavorite actions
Database:
Add user_favorite_projects table with migration (023_add_user_favorite_projects.py)
Foreign keys to users and projects with CASCADE delete
Unique constraint preventing duplicate favorites
Indexes on user_id and project_id for query optimization
Models:
User model: Add favorite_projects relationship with helper methods
add_favorite_project() - add project to favorites
remove_favorite_project() - remove from favorites
is_project_favorite() - check favorite status
get_favorite_projects() - retrieve favorites with status filter
Project model: Add is_favorited_by() method and include favorite status in to_dict()
Export UserFavoriteProject model in app/models/__init__.py
Routes:
Add /projects/<id>/favorite POST endpoint to favorite a project
Add /projects/<id>/unfavorite POST endpoint to unfavorite a project
Update /projects GET route to support favorites=true query parameter
Fix status filtering to work correctly with favorites JOIN query
Add /reports/export/form GET endpoint for enhanced CSV export form
Templates:
Update projects/list.html:
Add favorites filter dropdown to filter form (5-column grid)
Add star icon column with Font Awesome icons (filled/unfilled)
Add JavaScript toggleFavorite() function for AJAX favorite toggling
Improve hover states and transitions for better UX
Pass favorite_project_ids and favorites_only to template
Update reports/index.html:
Update CSV export link to point to new export form
Add icon and improve hover styling
Reports:
Enhance CSV export functionality with dedicated form page
Add filter options for users, projects, clients, and date ranges
Set default date range to last 30 days
Import Client model and or_ operator for advanced filtering
Testing:
Comprehensive test suite in tests/test_favorite_projects.py (550+ lines)
Model tests for UserFavoriteProject creation and validation
User/Project method tests for favorite operations
Route tests for favorite/unfavorite endpoints
Filtering tests for favorites-only view
Relationship tests for cascade delete behavior
Smoke tests for complete workflows
Coverage for edge cases and error handling
Documentation:
Add comprehensive feature documentation in docs/FAVORITE_PROJECTS_FEATURE.md
User guide with step-by-step instructions
Technical implementation details
API documentation for new endpoints
Migration guide and troubleshooting
Performance and security considerations
Template Cleanup:
Remove duplicate templates from root templates/ directory
Admin templates (dashboard, users, settings, OIDC debug, etc.)
Client CRUD templates
Error page templates
Invoice templates
Project templates
Report templates
Timer templates
All templates now properly located in app/templates/
Breaking Changes:
None - fully backward compatible
Migration Required:
Run alembic upgrade head to create user_favorite_projects table
2025-10-23 21:15:16 +02:00

622 lines
48 KiB
HTML

{% extends "base.html" %}
{% block title %}{{ _('Help') }} - {{ app_name }}{% endblock %}
{% block content %}
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-6">
<div>
<h1 class="text-2xl font-bold">{{ _('Help') }}</h1>
<p class="text-text-muted-light dark:text-text-muted-dark">{{ _('Complete documentation and user guide') }}</p>
</div>
<div class="text-sm text-text-muted-light dark:text-text-muted-dark mt-2 md:mt-0">
<i class="fas fa-question-circle"></i> / {{ _('Help') }}
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-5 gap-6">
<!-- Left sticky navigation -->
<aside class="lg:col-span-1">
<div class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark rounded-lg shadow p-4 lg:sticky lg:top-4">
<h3 class="font-semibold mb-3"><i class="fas fa-list mr-2"></i>{{ _('Quick Navigation') }}</h3>
<div class="relative mb-3">
<i class="fas fa-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"></i>
<input id="help-nav-filter" type="text" placeholder="{{ _('Filter sections...') }}" class="w-full pl-9 pr-3 py-2 text-sm rounded border border-border-light dark:border-border-dark bg-background-light dark:bg-background-dark" />
</div>
<nav id="help-nav" class="flex flex-col text-sm">
<a class="help-link py-1 hover:text-primary" href="#quick-start"><i class="fas fa-rocket mr-2"></i>{{ _('Quick Start') }}</a>
<a class="help-link py-1 hover:text-primary" href="#time-tracking"><i class="fas fa-stopwatch mr-2"></i>{{ _('Time Tracking') }}</a>
<a class="help-link py-1 hover:text-primary" href="#project-management"><i class="fas fa-project-diagram mr-2"></i>{{ _('Project Management') }}</a>
<a class="help-link py-1 hover:text-primary" href="#client-management"><i class="fas fa-building mr-2"></i>{{ _('Client Management') }}</a>
<a class="help-link py-1 hover:text-primary" href="#task-management"><i class="fas fa-tasks mr-2"></i>{{ _('Task Management') }}</a>
<a class="help-link py-1 hover:text-primary" href="#invoicing"><i class="fas fa-file-invoice-dollar mr-2"></i>{{ _('Invoicing') }}</a>
<a class="help-link py-1 hover:text-primary" href="#reports-analytics"><i class="fas fa-chart-line mr-2"></i>{{ _('Reports & Analytics') }}</a>
{% if current_user.is_admin %}
<a class="help-link py-1 hover:text-primary" href="#admin-features"><i class="fas fa-cog mr-2"></i>{{ _('Admin Features') }}</a>
{% endif %}
<a class="help-link py-1 hover:text-primary" href="#mobile-usage"><i class="fas fa-mobile-alt mr-2"></i>{{ _('Mobile Usage') }}</a>
<a class="help-link py-1 hover:text-primary" href="#troubleshooting"><i class="fas fa-tools mr-2"></i>{{ _('Troubleshooting') }}</a>
</nav>
</div>
</aside>
<!-- Main content -->
<section class="lg:col-span-4 space-y-8">
<!-- Hero -->
<div class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow text-center">
<h2 class="text-xl font-semibold mb-1">{{ _('TimeTracker Help Center') }}</h2>
<p class="text-text-muted-light dark:text-text-muted-dark">{{ _('Everything you need to know to get the most out of TimeTracker') }}</p>
<div class="flex flex-wrap gap-2 justify-center mt-4">
<a href="{{ url_for('timer.manual_entry') }}" class="px-3 py-2 rounded-lg bg-primary text-white text-sm hover:opacity-90">
<i class="fas fa-play mr-1"></i>{{ _('Start Tracking Time') }}
</a>
<a href="{{ url_for('projects.list_projects') }}" class="px-3 py-2 rounded-lg border border-border-light dark:border-border-dark text-sm hover:bg-background-light dark:hover:bg-background-dark">
<i class="fas fa-project-diagram mr-1"></i>{{ _('View Projects') }}
</a>
<a href="{{ url_for('reports.reports') }}" class="px-3 py-2 rounded-lg border border-sky-600 text-sky-600 text-sm hover:bg-sky-50 dark:hover:bg-sky-900/20">
<i class="fas fa-chart-bar mr-1"></i>{{ _('Generate Reports') }}
</a>
{% if current_user.is_admin %}
<a href="{{ url_for('admin.settings') }}" class="px-3 py-2 rounded-lg border border-amber-600 text-amber-600 text-sm hover:bg-amber-50 dark:hover:bg-amber-900/20">
<i class="fas fa-cog mr-1"></i>{{ _('System Settings') }}
</a>
{% endif %}
</div>
</div>
<!-- Quick Start -->
<section id="quick-start" class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow">
<h3 class="text-lg font-semibold mb-4"><i class="fas fa-rocket text-primary mr-2"></i>{{ _('Quick Start Guide') }}</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
<div>
<h4 class="font-semibold mb-2">{{ _('For New Users') }}</h4>
<ol class="list-decimal ml-5 space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Log in with your username (no password required)') }}</li>
<li>{{ _('Explore the dashboard to see your overview') }}</li>
<li>{{ _('Start your first timer on an existing project') }}</li>
<li>{{ _('View your time entries in reports') }}</li>
</ol>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('For Administrators') }}</h4>
<ol class="list-decimal ml-5 space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Set up clients in the Client Management section') }}</li>
<li>{{ _('Create projects and assign them to clients') }}</li>
<li>{{ _('Configure system settings (timezone, currency, etc.)') }}</li>
<li>{{ _('Manage users and permissions') }}</li>
</ol>
</div>
</div>
<div class="mt-4 flex items-start gap-3 p-3 rounded-lg border border-sky-600/30 bg-sky-50 dark:bg-sky-900/20 text-sm">
<i class="fas fa-lightbulb text-sky-600 mt-0.5"></i>
<p class="text-text-muted-light dark:text-text-muted-dark"><strong>{{ _('Pro Tip:') }}</strong> {{ _('Use the mobile-friendly interface to track time on the go. The timer continues running even if you close your browser!') }}</p>
</div>
</section>
<!-- Time Tracking -->
<section id="time-tracking" class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow">
<h3 class="text-lg font-semibold mb-4"><i class="fas fa-stopwatch text-green-600 mr-2"></i>{{ _('Time Tracking') }}</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm mb-4">
<div class="bg-background-light dark:bg-background-dark/40 p-4 rounded border border-border-light dark:border-border-dark">
<h4 class="font-semibold mb-1">{{ _('Smart Timers') }}</h4>
<p class="text-text-muted-light dark:text-text-muted-dark">{{ _('Real-time tracking with automatic idle detection and WebSocket updates') }}</p>
</div>
<div class="bg-background-light dark:bg-background-dark/40 p-4 rounded border border-border-light dark:border-border-dark">
<h4 class="font-semibold mb-1">{{ _('Manual Entry') }}</h4>
<p class="text-text-muted-light dark:text-text-muted-dark">{{ _('Log time manually with custom start and end times') }}</p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
<div>
<h4 class="font-semibold mb-2">{{ _('Starting a Timer') }}</h4>
<ol class="list-decimal ml-5 space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Navigate to the Timer page or dashboard') }}</li>
<li>{{ _('Select a project from the dropdown') }}</li>
<li>{{ _('Optionally select a task for more detailed tracking') }}</li>
<li>{{ _('Add notes about what you\'re working on (optional)') }}</li>
<li>{{ _('Add tags separated by commas (optional)') }}</li>
<li>{{ _('Click "Start Timer"') }}</li>
</ol>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('Timer Features') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-check text-green-600 mr-2"></i>{{ _('Real-time duration display') }}</li>
<li><i class="fas fa-check text-green-600 mr-2"></i>{{ _('Continues running if browser closes') }}</li>
<li><i class="fas fa-check text-green-600 mr-2"></i>{{ _('Automatic idle detection (configurable)') }}</li>
<li><i class="fas fa-check text-green-600 mr-2"></i>{{ _('One active timer per user (configurable)') }}</li>
<li><i class="fas fa-check text-green-600 mr-2"></i>{{ _('WebSocket live updates') }}</li>
</ul>
</div>
</div>
<div class="mt-6">
<h4 class="font-semibold mb-2">{{ _('Manual Time Entry') }}</h4>
<p class="text-sm text-text-muted-light dark:text-text-muted-dark mb-3">{{ _('Create time entries manually when you need to record time spent away from the computer or adjust existing entries.') }}</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
<div>
<h5 class="font-semibold">{{ _('Required Information') }}</h5>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Project selection') }}</li>
<li>{{ _('Start date and time') }}</li>
<li>{{ _('End date and time') }}</li>
</ul>
</div>
<div>
<h5 class="font-semibold">{{ _('Optional Information') }}</h5>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Task assignment') }}</li>
<li>{{ _('Description/notes') }}</li>
<li>{{ _('Tags for categorization') }}</li>
<li>{{ _('Billable status override') }}</li>
</ul>
</div>
</div>
</div>
</section>
<!-- Project Management -->
<section id="project-management" class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow">
<h3 class="text-lg font-semibold mb-4"><i class="fas fa-project-diagram text-sky-600 mr-2"></i>{{ _('Project Management') }}</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
<div>
<h4 class="font-semibold mb-2">{{ _('Project Information') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-tag text-primary mr-2"></i><strong>{{ _('Name') }}:</strong> {{ _('Descriptive project name') }}</li>
<li><i class="fas fa-building text-green-600 mr-2"></i><strong>{{ _('Client') }}:</strong> {{ _('Associated client organization') }}</li>
<li><i class="fas fa-align-left text-sky-600 mr-2"></i><strong>{{ _('Description') }}:</strong> {{ _('Project details and scope') }}</li>
<li><i class="fas fa-calendar text-amber-600 mr-2"></i><strong>{{ _('Status') }}:</strong> {{ _('Active, completed, or archived') }}</li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('Billing Information') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-dollar-sign text-green-600 mr-2"></i><strong>{{ _('Billable') }}:</strong> {{ _('Whether time should be tracked for billing') }}</li>
<li><i class="fas fa-money-bill text-sky-600 mr-2"></i><strong>{{ _('Hourly Rate') }}:</strong> {{ _('Rate for billable time calculations') }}</li>
<li><i class="fas fa-hashtag text-amber-600 mr-2"></i><strong>{{ _('Billing Reference') }}:</strong> {{ _('PO number or billing code') }}</li>
</ul>
</div>
</div>
{% if current_user.is_admin %}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm mt-6">
<div>
<h4 class="font-semibold mb-2">{{ _('Project Operations') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Create new projects with client relationships') }}</li>
<li>{{ _('Edit existing projects to update details') }}</li>
<li>{{ _('Archive projects to hide from timers (preserves data)') }}</li>
<li>{{ _('Delete projects (removes all associated time entries)') }}</li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('Best Practices') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Use descriptive project names') }}</li>
<li>{{ _('Set accurate hourly rates for billing') }}</li>
<li>{{ _('Archive instead of delete when possible') }}</li>
<li>{{ _('Use billing references for external tracking') }}</li>
</ul>
</div>
</div>
{% endif %}
</section>
<!-- Client Management -->
<section id="client-management" class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow">
<h3 class="text-lg font-semibold mb-4"><i class="fas fa-building text-amber-600 mr-2"></i>{{ _('Client Management') }}</h3>
<p class="text-sm text-text-muted-light dark:text-text-muted-dark mb-4">{{ _('The client management system helps organize your work by client organizations, preventing errors and streamlining project creation.') }}</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
<div>
<h4 class="font-semibold mb-2">{{ _('Client Information') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-building text-primary mr-2"></i><strong>{{ _('Organization Name') }}:</strong> {{ _('Company or client name') }}</li>
<li><i class="fas fa-user text-green-600 mr-2"></i><strong>{{ _('Contact Person') }}:</strong> {{ _('Primary contact details') }}</li>
<li><i class="fas fa-envelope text-sky-600 mr-2"></i><strong>{{ _('Email & Phone') }}:</strong> {{ _('Contact information') }}</li>
<li><i class="fas fa-map-marker-alt text-amber-600 mr-2"></i><strong>{{ _('Address') }}:</strong> {{ _('Business address') }}</li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('Benefits') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-check text-green-600 mr-2"></i>{{ _('Dropdown selection prevents typos') }}</li>
<li><i class="fas fa-check text-green-600 mr-2"></i>{{ _('Default rates auto-populate projects') }}</li>
<li><i class="fas fa-check text-green-600 mr-2"></i>{{ _('Consistent client naming') }}</li>
<li><i class="fas fa-check text-green-600 mr-2"></i>{{ _('Easier project organization') }}</li>
</ul>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 text-sm mt-6">
<div class="text-center p-4 rounded border border-border-light dark:border-border-dark">
<i class="fas fa-project-diagram text-primary mb-2"></i>
<h5 class="font-semibold">{{ _('Project Count') }}</h5>
<p class="text-xs text-text-muted-light dark:text-text-muted-dark">{{ _('Total and active projects') }}</p>
</div>
<div class="text-center p-4 rounded border border-border-light dark:border-border-dark">
<i class="fas fa-clock text-green-600 mb-2"></i>
<h5 class="font-semibold">{{ _('Time Tracking') }}</h5>
<p class="text-xs text-text-muted-light dark:text-text-muted-dark">{{ _('Total hours worked') }}</p>
</div>
<div class="text-center p-4 rounded border border-border-light dark:border-border-dark">
<i class="fas fa-dollar-sign text-sky-600 mb-2"></i>
<h5 class="font-semibold">{{ _('Cost Estimation') }}</h5>
<p class="text-xs text-text-muted-light dark:text-text-muted-dark">{{ _('Estimated billing amounts') }}</p>
</div>
</div>
</section>
<!-- Task Management -->
<section id="task-management" class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow">
<h3 class="text-lg font-semibold mb-4"><i class="fas fa-tasks text-red-500 mr-2"></i>{{ _('Task Management') }}</h3>
<p class="text-sm text-text-muted-light dark:text-text-muted-dark mb-4">{{ _('Break down projects into manageable tasks with detailed tracking and progress monitoring.') }}</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
<div>
<h4 class="font-semibold mb-2">{{ _('Task Properties') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-tag text-primary mr-2"></i><strong>{{ _('Name & Description') }}:</strong> {{ _('Clear task identification') }}</li>
<li><i class="fas fa-flag text-amber-600 mr-2"></i><strong>{{ _('Priority Levels') }}:</strong> {{ _('Low, Medium, High, Urgent') }}</li>
<li><i class="fas fa-calendar text-sky-600 mr-2"></i><strong>{{ _('Due Dates') }}:</strong> {{ _('Deadline tracking') }}</li>
<li><i class="fas fa-user text-green-600 mr-2"></i><strong>{{ _('Assignment') }}:</strong> {{ _('Task ownership') }}</li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('Status Tracking') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-circle text-gray-400 mr-2"></i>{{ _('To Do - Not started') }}</li>
<li><i class="fas fa-circle text-primary mr-2"></i>{{ _('In Progress - Currently working') }}</li>
<li><i class="fas fa-circle text-amber-500 mr-2"></i>{{ _('Review - Ready for review') }}</li>
<li><i class="fas fa-circle text-green-600 mr-2"></i>{{ _('Done - Completed') }}</li>
<li><i class="fas fa-circle text-red-500 mr-2"></i>{{ _('Cancelled - Not needed') }}</li>
</ul>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm mt-6">
<div>
<h4 class="font-semibold mb-2">{{ _('Time Tracking Features') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Start timers directly from tasks') }}</li>
<li>{{ _('Link time entries to specific tasks') }}</li>
<li>{{ _('Track estimated vs actual hours') }}</li>
<li>{{ _('Monitor task progress automatically') }}</li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('Task Views') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('My Tasks - Your assigned tasks') }}</li>
<li>{{ _('All Tasks - Complete task list') }}</li>
<li>{{ _('Overdue Tasks - Past due items') }}</li>
<li>{{ _('Project Tasks - Tasks within projects') }}</li>
</ul>
</div>
</div>
</section>
<!-- Invoicing -->
<section id="invoicing" class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow">
<h3 class="text-lg font-semibold mb-4"><i class="fas fa-file-invoice-dollar text-green-600 mr-2"></i>{{ _('Professional Invoicing') }}</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm mb-4">
<div class="bg-background-light dark:bg-background-dark/40 p-4 rounded border border-border-light dark:border-border-dark">
<h4 class="font-semibold mb-1">{{ _('Core Features') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-file-pdf text-red-500 mr-2"></i>{{ _('Professional PDF generation') }}</li>
<li><i class="fas fa-palette text-primary mr-2"></i>{{ _('Company branding and logos') }}</li>
<li><i class="fas fa-hashtag text-sky-600 mr-2"></i>{{ _('Automatic invoice numbering') }}</li>
<li><i class="fas fa-calculator text-green-600 mr-2"></i>{{ _('Tax calculations') }}</li>
</ul>
</div>
<div class="bg-background-light dark:bg-background-dark/40 p-4 rounded border border-border-light dark:border-border-dark">
<h4 class="font-semibold mb-1">{{ _('Time Integration') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-clock text-amber-600 mr-2"></i>{{ _('Generate from time entries') }}</li>
<li><i class="fas fa-layer-group text-sky-600 mr-2"></i>{{ _('Smart grouping by task/project') }}</li>
<li><i class="fas fa-shield-alt text-green-600 mr-2"></i>{{ _('Prevent double-billing') }}</li>
<li><i class="fas fa-money-bill text-primary mr-2"></i>{{ _('Use project hourly rates') }}</li>
</ul>
</div>
</div>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
<div class="text-center p-4 rounded border border-border-light dark:border-border-dark">
<div class="mx-auto mb-2 w-10 h-10 rounded-full flex items-center justify-center bg-primary/10"><span class="font-bold text-primary">1</span></div>
<h5 class="font-semibold">{{ _('Create Invoice') }}</h5>
<p class="text-xs text-text-muted-light dark:text-text-muted-dark">{{ _('Set up client and project details') }}</p>
</div>
<div class="text-center p-4 rounded border border-border-light dark:border-border-dark">
<div class="mx-auto mb-2 w-10 h-10 rounded-full flex items-center justify-center bg-green-600/10"><span class="font-bold text-green-600">2</span></div>
<h5 class="font-semibold">{{ _('Add Items') }}</h5>
<p class="text-xs text-text-muted-light dark:text-text-muted-dark">{{ _('Generate from time or add manually') }}</p>
</div>
<div class="text-center p-4 rounded border border-border-light dark:border-border-dark">
<div class="mx-auto mb-2 w-10 h-10 rounded-full flex items-center justify-center bg-sky-600/10"><span class="font-bold text-sky-600">3</span></div>
<h5 class="font-semibold">{{ _('Review & Send') }}</h5>
<p class="text-xs text-text-muted-light dark:text-text-muted-dark">{{ _('Export PDF and update status') }}</p>
</div>
<div class="text-center p-4 rounded border border-border-light dark:border-border-dark">
<div class="mx-auto mb-2 w-10 h-10 rounded-full flex items-center justify-center bg-amber-600/10"><span class="font-bold text-amber-600">4</span></div>
<h5 class="font-semibold">{{ _('Track Payment') }}</h5>
<p class="text-xs text-text-muted-light dark:text-text-muted-dark">{{ _('Monitor status and payments') }}</p>
</div>
</div>
</section>
<!-- Reports & Analytics -->
<section id="reports-analytics" class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow">
<h3 class="text-lg font-semibold mb-4"><i class="fas fa-chart-line text-sky-600 mr-2"></i>{{ _('Reports & Analytics') }}</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm mb-4">
<div class="bg-background-light dark:bg-background-dark/40 p-4 rounded border border-border-light dark:border-border-dark">
<h4 class="font-semibold mb-1">{{ _('Standard Reports') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Project Report - Time breakdown by project') }}</li>
<li>{{ _('User Report - Individual performance metrics') }}</li>
<li>{{ _('Summary Report - Key metrics and trends') }}</li>
<li>{{ _('Time Entry Report - Detailed time logs') }}</li>
</ul>
</div>
<div class="bg-background-light dark:bg-background-dark/40 p-4 rounded border border-border-light dark:border-border-dark">
<h4 class="font-semibold mb-1">{{ _('Export Options') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('CSV Export - For external analysis') }}</li>
<li>{{ _('Configurable delimiters') }}</li>
<li>{{ _('Custom date ranges') }}</li>
<li>{{ _('Filtered data export') }}</li>
</ul>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
<div>
<h4 class="font-semibold mb-2">{{ _('Filter Options') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-calendar text-primary mr-2"></i>{{ _('Date Range - Custom start and end dates') }}</li>
<li><i class="fas fa-project-diagram text-green-600 mr-2"></i>{{ _('Project - Filter by specific projects') }}</li>
<li><i class="fas fa-user text-sky-600 mr-2"></i>{{ _('User - Filter by team members') }}</li>
<li><i class="fas fa-building text-amber-600 mr-2"></i>{{ _('Client - Filter by client organization') }}</li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('Visual Analytics') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-chart-bar text-primary mr-2"></i>{{ _('Interactive bar charts') }}</li>
<li><i class="fas fa-chart-pie text-green-600 mr-2"></i>{{ _('Time distribution pie charts') }}</li>
<li><i class="fas fa-chart-line text-sky-600 mr-2"></i>{{ _('Trend analysis over time') }}</li>
<li><i class="fas fa-mobile-alt text-amber-600 mr-2"></i>{{ _('Mobile-optimized charts') }}</li>
</ul>
</div>
</div>
</section>
{% if current_user.is_admin %}
<!-- Admin Features -->
<section id="admin-features" class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow">
<h3 class="text-lg font-semibold mb-4"><i class="fas fa-cog text-amber-600 mr-2"></i>{{ _('Administrator Features') }}</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
<div>
<h4 class="font-semibold mb-2">{{ _('User Management') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Create new users with username-only authentication') }}</li>
<li>{{ _('Assign user roles (user or admin)') }}</li>
<li>{{ _('Activate/deactivate user accounts') }}</li>
<li>{{ _('View user statistics and activity') }}</li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('Access Control') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Role-based permissions') }}</li>
<li>{{ _('Admin-only system settings') }}</li>
<li>{{ _('User data access controls') }}</li>
<li>{{ _('Audit trail for admin actions') }}</li>
</ul>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm mt-6">
<div>
<h4 class="font-semibold mb-2">{{ _('General Settings') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-globe text-primary mr-2"></i>{{ _('Timezone and locale settings') }}</li>
<li><i class="fas fa-dollar-sign text-green-600 mr-2"></i>{{ _('Currency configuration') }}</li>
<li><i class="fas fa-clock text-sky-600 mr-2"></i>{{ _('Time rounding rules') }}</li>
<li><i class="fas fa-user-plus text-amber-600 mr-2"></i>{{ _('Self-registration settings') }}</li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('Timer Settings') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-pause text-primary mr-2"></i>{{ _('Idle timeout configuration') }}</li>
<li><i class="fas fa-play text-green-600 mr-2"></i>{{ _('Single active timer mode') }}</li>
<li><i class="fas fa-stopwatch text-sky-600 mr-2"></i>{{ _('Timer display preferences') }}</li>
<li><i class="fas fa-bell text-amber-600 mr-2"></i>{{ _('Notification settings') }}</li>
</ul>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm mt-6">
<div>
<h4 class="font-semibold mb-2">{{ _('Database Management') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Create manual database backups') }}</li>
<li>{{ _('View database migration status') }}</li>
<li>{{ _('Monitor database performance') }}</li>
<li>{{ _('Clean up old data and logs') }}</li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('System Monitoring') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('View system information and health') }}</li>
<li>{{ _('Monitor application performance') }}</li>
<li>{{ _('Review system logs and errors') }}</li>
</ul>
</div>
</div>
</section>
{% endif %}
<!-- Mobile Usage -->
<section id="mobile-usage" class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow">
<h3 class="text-lg font-semibold mb-4"><i class="fas fa-mobile-alt text-primary mr-2"></i>{{ _('Mobile Usage') }}</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
<div>
<h4 class="font-semibold mb-2">{{ _('Mobile-Friendly Features') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-mobile-alt text-primary mr-2"></i>{{ _('Optimized for phones and tablets') }}</li>
<li><i class="fas fa-hand-pointer text-green-600 mr-2"></i>{{ _('Touch-friendly interface') }}</li>
<li><i class="fas fa-expand-arrows-alt text-sky-600 mr-2"></i>{{ _('Adaptive layouts for all screen sizes') }}</li>
<li><i class="fas fa-eye text-amber-600 mr-2"></i>{{ _('High contrast for outdoor visibility') }}</li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('Mobile Navigation') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li><i class="fas fa-bars text-primary mr-2"></i>{{ _('Bottom tab bar for easy access') }}</li>
<li><i class="fas fa-home text-green-600 mr-2"></i>{{ _('Quick access to dashboard') }}</li>
<li><i class="fas fa-plus text-sky-600 mr-2"></i>{{ _('One-tap time logging') }}</li>
<li><i class="fas fa-chart-bar text-amber-600 mr-2"></i>{{ _('Mobile-optimized reports') }}</li>
</ul>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm mt-6">
<div>
<h4 class="font-semibold mb-2">{{ _('Installation') }}</h4>
<ol class="list-decimal ml-5 space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Open TimeTracker in your mobile browser') }}</li>
<li>{{ _('Look for "Add to Home Screen" option') }}</li>
<li>{{ _('Follow browser-specific installation prompts') }}</li>
<li>{{ _('Launch from your home screen like a native app') }}</li>
</ol>
</div>
<div>
<h4 class="font-semibold mb-2">{{ _('PWA Benefits') }}</h4>
<ul class="space-y-1 text-text-muted-light dark:text-text-muted-dark">
<li>{{ _('Offline capability for basic functions') }}</li>
<li>{{ _('Faster loading times') }}</li>
<li>{{ _('Native app-like experience') }}</li>
<li>{{ _('Push notifications (where supported)') }}</li>
</ul>
</div>
</div>
</section>
<!-- Troubleshooting -->
<section id="troubleshooting" class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow">
<h3 class="text-lg font-semibold mb-4"><i class="fas fa-tools text-red-500 mr-2"></i>{{ _('Troubleshooting & FAQ') }}</h3>
<div class="space-y-3 text-sm">
<details class="group border border-border-light dark:border-border-dark rounded p-4">
<summary class="font-semibold cursor-pointer flex items-center"><i class="fas fa-stopwatch mr-2"></i>{{ _('What happens if I forget to stop my timer?') }}</summary>
<p class="mt-2 text-text-muted-light dark:text-text-muted-dark">{{ _('The timer will continue running until you stop it manually. You can see your active timer on the dashboard and timer page. The timer persists even if you close your browser or restart your device. If idle detection is enabled, the timer may pause automatically after the configured timeout period.') }}</p>
</details>
<details class="group border border-border-light dark:border-border-dark rounded p-4">
<summary class="font-semibold cursor-pointer flex items-center"><i class="fas fa-edit mr-2"></i>{{ _("Can I edit time entries after they're created?") }}</summary>
<p class="mt-2 text-text-muted-light dark:text-text-muted-dark">{{ _('Yes, you can edit any time entry by clicking the edit button in the time entry list. You can modify the project, start/end times, notes, tags, billable status, and task assignment. Admins can edit all time entries, while regular users can only edit their own entries.') }}</p>
</details>
<details class="group border border-border-light dark:border-border-dark rounded p-4">
<summary class="font-semibold cursor-pointer flex items-center"><i class="fas fa-project-diagram mr-2"></i>{{ _('How do I track time for multiple projects?') }}</summary>
<p class="mt-2 text-text-muted-light dark:text-text-muted-dark">{{ _('By default, you can only have one active timer at a time. To switch projects, stop your current timer and start a new one for the different project. Alternatively, you can create manual time entries for past work or configure the system to allow multiple active timers (admin setting).') }}</p>
</details>
<details class="group border border-border-light dark:border-border-dark rounded p-4">
<summary class="font-semibold cursor-pointer flex items-center"><i class="fas fa-download mr-2"></i>{{ _('How do I export my time data?') }}</summary>
<p class="mt-2 text-text-muted-light dark:text-text-muted-dark">{{ _('Go to the Reports page and use the "Export CSV" feature. You can apply filters to export specific data, or export all time entries. The CSV file includes all time entry details and can be opened in Excel or other spreadsheet applications. You can also configure the delimiter for different regional standards.') }}</p>
</details>
<details class="group border border-border-light dark:border-border-dark rounded p-4">
<summary class="font-semibold cursor-pointer flex items-center"><i class="fas fa-dollar-sign mr-2"></i>{{ _("What's the difference between billable and non-billable time?") }}</summary>
<p class="mt-2 text-text-muted-light dark:text-text-muted-dark">{{ _('Billable time is tracked for client billing purposes and can have an hourly rate associated with it. Non-billable time is for internal work that doesn\'t get charged to clients. You can mark individual time entries as billable or non-billable, and projects can have default billable settings. This distinction is crucial for accurate invoicing and profitability analysis.') }}</p>
</details>
<details class="group border border-border-light dark:border-border-dark rounded p-4">
<summary class="font-semibold cursor-pointer flex items-center"><i class="fas fa-file-invoice-dollar mr-2"></i>{{ _('How do I create an invoice from my time entries?') }}</summary>
<p class="mt-2 text-text-muted-light dark:text-text-muted-dark">{{ _('Navigate to Invoices → Create Invoice, set up the client and project details, then use "Generate from Time Entries" to automatically create invoice items from your tracked time. You can filter by date range and project, and the system will group time entries intelligently. Review the generated items and export as a professional PDF.') }}</p>
</details>
<details class="group border border-border-light dark:border-border-dark rounded p-4">
<summary class="font-semibold cursor-pointer flex items-center"><i class="fas fa-mobile-alt mr-2"></i>{{ _('Can I use TimeTracker on my mobile device?') }}</summary>
<p class="mt-2 text-text-muted-light dark:text-text-muted-dark">{{ _('Yes! TimeTracker is fully responsive and works great on mobile devices. You can install it as a Progressive Web App (PWA) for a native-like experience. The mobile interface includes a bottom tab bar for easy navigation and touch-optimized controls for time tracking on the go.') }}</p>
</details>
<details class="group border border-border-light dark:border-border-dark rounded p-4">
<summary class="font-semibold cursor-pointer flex items-center"><i class="fas fa-question-circle mr-2"></i>{{ _('Where can I get additional help?') }}</summary>
<div class="mt-2 grid grid-cols-1 md:grid-cols-2 gap-4 text-text-muted-light dark:text-text-muted-dark">
<div>
<h4 class="font-semibold">{{ _('Documentation') }}</h4>
<p>{{ _('This help page covers most common questions and features.') }}</p>
</div>
<div>
<h4 class="font-semibold">{{ _('Community Support') }}</h4>
<p>{{ _('Report issues and request features on') }} <a class="text-primary" href="https://github.com/drytrix/TimeTracker/issues" target="_blank">GitHub Issues</a>.</p>
</div>
</div>
{% if current_user.is_admin %}
<div class="mt-3 p-3 rounded border border-sky-600/30 bg-sky-50 dark:bg-sky-900/20">
<i class="fas fa-info-circle mr-2"></i>{{ _('As an admin, you can access additional system information and diagnostics in the') }} <a class="text-primary" href="{{ url_for('admin.system_info') }}">{{ _('System Info') }}</a> {{ _('section.') }}
</div>
{% endif %}
</details>
</div>
</section>
<!-- Footer Help -->
<div class="bg-card-light dark:bg-card-dark border border-border-light dark:border-border-dark p-6 rounded-lg shadow text-center">
<h3 class="text-lg font-semibold">{{ _('Still Need Help?') }}</h3>
<p class="text-sm text-text-muted-light dark:text-text-muted-dark mb-4">{{ _('Can\'t find what you\'re looking for? Here are additional resources:') }}</p>
<div class="flex flex-wrap gap-3 justify-center">
{% if current_user.is_admin %}
<a href="{{ url_for('admin.system_info') }}" class="px-4 py-2 rounded-lg border border-primary text-primary hover:bg-primary/10">
<i class="fas fa-info-circle mr-1"></i>{{ _('System Info') }}
</a>
{% endif %}
<a href="https://github.com/drytrix/TimeTracker" target="_blank" rel="noopener" class="px-4 py-2 rounded-lg border border-border-light dark:border-border-dark hover:bg-background-light dark:hover:bg-background-dark">
<i class="fab fa-github mr-1"></i>{{ _('GitHub Repository') }}
</a>
<a href="https://github.com/drytrix/TimeTracker/issues" target="_blank" rel="noopener" class="px-4 py-2 rounded-lg border border-amber-600 text-amber-600 hover:bg-amber-50 dark:hover:bg-amber-900/20">
<i class="fas fa-bug mr-1"></i>{{ _('Report Issue') }}
</a>
<a href="https://buymeacoffee.com/DryTrix" target="_blank" rel="noopener" class="px-4 py-2 rounded-lg border border-green-600 text-green-600 hover:bg-green-50 dark:hover:bg-green-900/20">
<i class="fas fa-mug-saucer mr-1"></i>{{ _('Support Development') }}
</a>
</div>
</div>
</section>
</div>
{% endblock %}
{% block scripts_extra %}
<script>
document.addEventListener('DOMContentLoaded', function(){
const links = Array.from(document.querySelectorAll('#help-nav .help-link'));
const filter = document.getElementById('help-nav-filter');
// Smooth scroll
links.forEach(a => {
a.addEventListener('click', (e) => {
const targetId = a.getAttribute('href');
if (targetId && targetId.startsWith('#')) {
const el = document.querySelector(targetId);
if (el) {
e.preventDefault();
el.scrollIntoView({ behavior: 'smooth', block: 'start' });
history.replaceState(null, '', targetId);
}
}
});
});
// Active highlighting via IntersectionObserver
const sectionIds = links.map(a => a.getAttribute('href')).filter(Boolean);
const sections = sectionIds.map(id => document.querySelector(id)).filter(Boolean);
const byId = new Map(links.map(a => [a.getAttribute('href'), a]));
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const id = '#' + entry.target.id;
const link = byId.get(id);
if (!link) return;
if (entry.isIntersecting) {
links.forEach(l => l.classList.remove('text-primary','font-semibold'));
link.classList.add('text-primary','font-semibold');
}
});
}, { rootMargin: '-40% 0px -50% 0px', threshold: [0, 1] });
sections.forEach(s => observer.observe(s));
// Filter
if (filter) {
filter.addEventListener('input', () => {
const q = filter.value.toLowerCase().trim();
links.forEach(a => {
const txt = a.textContent.toLowerCase();
a.style.display = txt.includes(q) ? '' : 'none';
});
});
}
});
</script>
{% endblock %}