mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-01-21 20:09:57 -06:00
900 lines
30 KiB
HTML
900 lines
30 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>TimeTracker - Self-Hosted Time Tracking Solution</title>
|
|
<meta name="description" content="A robust, self-hosted time tracking application designed for teams and freelancers who need reliable time management without cloud dependencies.">
|
|
<meta name="keywords" content="time tracking, self-hosted, flask, python, docker, raspberry pi, open source">
|
|
|
|
<!-- Open Graph / Facebook -->
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:url" content="https://drytrix.github.io/TimeTracker/">
|
|
<meta property="og:title" content="TimeTracker - Self-Hosted Time Tracking Solution">
|
|
<meta property="og:description" content="A robust, self-hosted time tracking application designed for teams and freelancers who need reliable time management without cloud dependencies.">
|
|
<meta property="og:image" content="https://drytrix.github.io/TimeTracker/assets/og-image.png">
|
|
|
|
<!-- Twitter -->
|
|
<meta property="twitter:card" content="summary_large_image">
|
|
<meta property="twitter:url" content="https://drytrix.github.io/TimeTracker/">
|
|
<meta property="twitter:title" content="TimeTracker - Self-Hosted Time Tracking Solution">
|
|
<meta property="twitter:description" content="A robust, self-hosted time tracking application designed for teams and freelancers who need reliable time management without cloud dependencies.">
|
|
<meta property="twitter:image" content="https://drytrix.github.io/TimeTracker/assets/og-image.png">
|
|
|
|
<!-- Favicon -->
|
|
<link rel="icon" type="image/x-icon" href="assets/favicon.ico">
|
|
|
|
<!-- CSS -->
|
|
<style>
|
|
:root {
|
|
--primary-color: #2563eb;
|
|
--primary-dark: #1d4ed8;
|
|
--secondary-color: #64748b;
|
|
--accent-color: #f59e0b;
|
|
--success-color: #10b981;
|
|
--danger-color: #ef4444;
|
|
--background: #ffffff;
|
|
--surface: #f8fafc;
|
|
--text-primary: #1e293b;
|
|
--text-secondary: #64748b;
|
|
--border: #e2e8f0;
|
|
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
--shadow-lg: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
line-height: 1.6;
|
|
color: var(--text-primary);
|
|
background: var(--background);
|
|
}
|
|
|
|
.container {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
padding: 0 20px;
|
|
}
|
|
|
|
/* Header */
|
|
.header {
|
|
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-dark) 100%);
|
|
color: white;
|
|
padding: 80px 0;
|
|
text-align: center;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.header::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grain" width="100" height="100" patternUnits="userSpaceOnUse"><circle cx="50" cy="50" r="1" fill="white" opacity="0.1"/></pattern></defs><rect width="100" height="100" fill="url(%23grain)"/></svg>');
|
|
opacity: 0.3;
|
|
}
|
|
|
|
.header-content {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.logo {
|
|
font-size: 3.5rem;
|
|
font-weight: 700;
|
|
margin-bottom: 20px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 15px;
|
|
}
|
|
|
|
.tagline {
|
|
font-size: 1.5rem;
|
|
margin-bottom: 30px;
|
|
opacity: 0.9;
|
|
font-weight: 300;
|
|
}
|
|
|
|
.cta-buttons {
|
|
display: flex;
|
|
gap: 20px;
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.btn {
|
|
display: inline-block;
|
|
padding: 15px 30px;
|
|
border-radius: 8px;
|
|
text-decoration: none;
|
|
font-weight: 600;
|
|
transition: all 0.3s ease;
|
|
border: none;
|
|
cursor: pointer;
|
|
font-size: 1rem;
|
|
}
|
|
|
|
.btn-primary {
|
|
background: var(--accent-color);
|
|
color: white;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background: #d97706;
|
|
transform: translateY(-2px);
|
|
box-shadow: var(--shadow-lg);
|
|
}
|
|
|
|
.btn-secondary {
|
|
background: transparent;
|
|
color: white;
|
|
border: 2px solid white;
|
|
}
|
|
|
|
.btn-secondary:hover {
|
|
background: white;
|
|
color: var(--primary-color);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
/* Features Section */
|
|
.features {
|
|
padding: 100px 0;
|
|
background: var(--surface);
|
|
}
|
|
|
|
.section-title {
|
|
text-align: center;
|
|
font-size: 2.5rem;
|
|
margin-bottom: 20px;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.section-subtitle {
|
|
text-align: center;
|
|
font-size: 1.2rem;
|
|
color: var(--text-secondary);
|
|
margin-bottom: 60px;
|
|
max-width: 600px;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
}
|
|
|
|
.features-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
gap: 40px;
|
|
margin-top: 60px;
|
|
}
|
|
|
|
.feature-card {
|
|
background: white;
|
|
padding: 40px 30px;
|
|
border-radius: 16px;
|
|
box-shadow: var(--shadow);
|
|
transition: all 0.3s ease;
|
|
border: 1px solid var(--border);
|
|
}
|
|
|
|
.feature-card:hover {
|
|
transform: translateY(-5px);
|
|
box-shadow: var(--shadow-lg);
|
|
}
|
|
|
|
.feature-icon {
|
|
font-size: 3rem;
|
|
margin-bottom: 20px;
|
|
display: block;
|
|
}
|
|
|
|
.feature-title {
|
|
font-size: 1.5rem;
|
|
margin-bottom: 15px;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.feature-description {
|
|
color: var(--text-secondary);
|
|
line-height: 1.6;
|
|
}
|
|
|
|
/* Screenshots Section */
|
|
.screenshots {
|
|
padding: 100px 0;
|
|
background: white;
|
|
}
|
|
|
|
.screenshots-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
gap: 60px;
|
|
margin-top: 60px;
|
|
}
|
|
|
|
.screenshot-item {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 40px;
|
|
align-items: center;
|
|
background: var(--surface);
|
|
padding: 40px;
|
|
border-radius: 16px;
|
|
box-shadow: var(--shadow);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.screenshot-item:nth-child(even) {
|
|
grid-template-columns: 1fr 1fr;
|
|
}
|
|
|
|
.screenshot-item:nth-child(odd) {
|
|
grid-template-columns: 1fr 1fr;
|
|
}
|
|
|
|
.screenshot-item:hover {
|
|
transform: translateY(-5px);
|
|
box-shadow: var(--shadow-lg);
|
|
}
|
|
|
|
.screenshot-image {
|
|
text-align: center;
|
|
}
|
|
|
|
.screenshot-image img {
|
|
max-width: 100%;
|
|
height: auto;
|
|
border-radius: 8px;
|
|
box-shadow: var(--shadow);
|
|
border: 1px solid var(--border);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.screenshot-image img:hover {
|
|
transform: scale(1.02);
|
|
box-shadow: var(--shadow-lg);
|
|
}
|
|
|
|
.screenshot-caption h3 {
|
|
font-size: 1.8rem;
|
|
margin-bottom: 20px;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.screenshot-caption p {
|
|
color: var(--text-secondary);
|
|
line-height: 1.6;
|
|
font-size: 1.1rem;
|
|
}
|
|
|
|
/* Problem Section */
|
|
.problem {
|
|
padding: 100px 0;
|
|
background: white;
|
|
}
|
|
|
|
.problem-content {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 60px;
|
|
align-items: center;
|
|
}
|
|
|
|
.problem-text h2 {
|
|
font-size: 2.5rem;
|
|
margin-bottom: 30px;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.problem-list {
|
|
list-style: none;
|
|
}
|
|
|
|
.problem-list li {
|
|
padding: 15px 0;
|
|
border-bottom: 1px solid var(--border);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 15px;
|
|
}
|
|
|
|
.problem-list li:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.problem-icon {
|
|
color: var(--danger-color);
|
|
font-size: 1.5rem;
|
|
}
|
|
|
|
.solution-icon {
|
|
color: var(--success-color);
|
|
font-size: 1.5rem;
|
|
}
|
|
|
|
.problem-visual {
|
|
background: var(--surface);
|
|
padding: 40px;
|
|
border-radius: 16px;
|
|
text-align: center;
|
|
}
|
|
|
|
.problem-visual h3 {
|
|
font-size: 1.5rem;
|
|
margin-bottom: 20px;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.problem-visual p {
|
|
color: var(--text-secondary);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
/* Quick Start Section */
|
|
.quick-start {
|
|
padding: 100px 0;
|
|
background: var(--surface);
|
|
}
|
|
|
|
.steps {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
gap: 30px;
|
|
margin-top: 60px;
|
|
}
|
|
|
|
.step {
|
|
background: white;
|
|
padding: 30px;
|
|
border-radius: 12px;
|
|
box-shadow: var(--shadow);
|
|
text-align: center;
|
|
border: 1px solid var(--border);
|
|
}
|
|
|
|
.step-number {
|
|
background: var(--primary-color);
|
|
color: white;
|
|
width: 50px;
|
|
height: 50px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin: 0 auto 20px;
|
|
font-weight: bold;
|
|
font-size: 1.2rem;
|
|
}
|
|
|
|
.step-title {
|
|
font-size: 1.3rem;
|
|
margin-bottom: 15px;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.step-description {
|
|
color: var(--text-secondary);
|
|
line-height: 1.6;
|
|
}
|
|
|
|
/* Code Block */
|
|
.code-block {
|
|
background: #1e293b;
|
|
color: #e2e8f0;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
font-size: 0.9rem;
|
|
overflow-x: auto;
|
|
margin: 20px 0;
|
|
}
|
|
|
|
.code-block .comment {
|
|
color: #64748b;
|
|
}
|
|
|
|
.code-block .string {
|
|
color: #10b981;
|
|
}
|
|
|
|
/* Stats Section */
|
|
.stats {
|
|
padding: 80px 0;
|
|
background: var(--primary-color);
|
|
color: white;
|
|
}
|
|
|
|
.stats-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: 40px;
|
|
text-align: center;
|
|
}
|
|
|
|
.stat-item h3 {
|
|
font-size: 2.5rem;
|
|
margin-bottom: 10px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.stat-item p {
|
|
opacity: 0.9;
|
|
font-size: 1.1rem;
|
|
}
|
|
|
|
/* Footer */
|
|
.footer {
|
|
background: var(--text-primary);
|
|
color: white;
|
|
padding: 60px 0 30px;
|
|
text-align: center;
|
|
}
|
|
|
|
.footer-content {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
gap: 40px;
|
|
margin-bottom: 40px;
|
|
}
|
|
|
|
.footer-section h4 {
|
|
margin-bottom: 20px;
|
|
color: var(--accent-color);
|
|
}
|
|
|
|
.footer-section ul {
|
|
list-style: none;
|
|
}
|
|
|
|
.footer-section ul li {
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.footer-section ul li a {
|
|
color: #cbd5e1;
|
|
text-decoration: none;
|
|
transition: color 0.3s ease;
|
|
}
|
|
|
|
.footer-section ul li a:hover {
|
|
color: white;
|
|
}
|
|
|
|
.footer-bottom {
|
|
border-top: 1px solid #334155;
|
|
padding-top: 30px;
|
|
color: #cbd5e1;
|
|
}
|
|
|
|
.social-links {
|
|
display: flex;
|
|
gap: 20px;
|
|
justify-content: center;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.social-links a {
|
|
color: #cbd5e1;
|
|
font-size: 1.5rem;
|
|
transition: color 0.3s ease;
|
|
}
|
|
|
|
.social-links a:hover {
|
|
color: var(--accent-color);
|
|
}
|
|
|
|
/* Responsive Design */
|
|
@media (max-width: 768px) {
|
|
.header {
|
|
padding: 60px 0;
|
|
}
|
|
|
|
.logo {
|
|
font-size: 2.5rem;
|
|
}
|
|
|
|
.tagline {
|
|
font-size: 1.2rem;
|
|
}
|
|
|
|
.cta-buttons {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
.problem-content {
|
|
grid-template-columns: 1fr;
|
|
gap: 40px;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 2rem;
|
|
}
|
|
|
|
.features-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.steps {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.screenshot-item {
|
|
grid-template-columns: 1fr;
|
|
gap: 30px;
|
|
padding: 30px;
|
|
}
|
|
|
|
.screenshot-item:nth-child(even) {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.screenshot-item:nth-child(odd) {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
|
|
/* Animations */
|
|
@keyframes fadeInUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.fade-in-up {
|
|
animation: fadeInUp 0.6s ease-out;
|
|
}
|
|
|
|
/* Scroll animations */
|
|
.scroll-animate {
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
transition: all 0.6s ease-out;
|
|
}
|
|
|
|
.scroll-animate.animate {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- Header -->
|
|
<header class="header">
|
|
<div class="container">
|
|
<div class="header-content">
|
|
<div class="logo">
|
|
⏱️ TimeTracker
|
|
</div>
|
|
<p class="tagline">Self-hosted time tracking for teams and freelancers</p>
|
|
<div class="cta-buttons">
|
|
<a href="https://github.com/DRYTRIX/TimeTracker" class="btn btn-primary">
|
|
🚀 Get Started
|
|
</a>
|
|
<a href="https://github.com/DRYTRIX/TimeTracker" class="btn btn-secondary">
|
|
📖 View Docs
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Features Section -->
|
|
<section class="features">
|
|
<div class="container">
|
|
<h2 class="section-title">Why Choose TimeTracker?</h2>
|
|
<p class="section-subtitle">Built for reliability, designed for simplicity, and engineered for performance</p>
|
|
|
|
<div class="features-grid">
|
|
<div class="feature-card scroll-animate">
|
|
<span class="feature-icon">🕐</span>
|
|
<h3 class="feature-title">Persistent Timers</h3>
|
|
<p class="feature-description">Server-side timers that survive browser restarts and computer reboots. Never lose track of your time again.</p>
|
|
</div>
|
|
|
|
<div class="feature-card scroll-animate">
|
|
<span class="feature-icon">☁️</span>
|
|
<h3 class="feature-title">Self-Hosted</h3>
|
|
<p class="feature-description">Full control over your data with no cloud dependencies. Deploy on your own infrastructure with confidence.</p>
|
|
</div>
|
|
|
|
<div class="feature-card scroll-animate">
|
|
<span class="feature-icon">📊</span>
|
|
<h3 class="feature-title">Rich Reporting</h3>
|
|
<p class="feature-description">Comprehensive reports and analytics with CSV export capabilities for external analysis and billing.</p>
|
|
</div>
|
|
|
|
<div class="feature-card scroll-animate">
|
|
<span class="feature-icon">👥</span>
|
|
<h3 class="feature-title">Team Management</h3>
|
|
<p class="feature-description">User roles, project organization, and billing support for teams of any size.</p>
|
|
</div>
|
|
|
|
<div class="feature-card scroll-animate">
|
|
<span class="feature-icon">🐳</span>
|
|
<h3 class="feature-title">Docker Ready</h3>
|
|
<p class="feature-description">Simple deployment with Docker and Docker Compose. Perfect for Raspberry Pi and production environments.</p>
|
|
</div>
|
|
|
|
<div class="feature-card scroll-animate">
|
|
<span class="feature-icon">🔒</span>
|
|
<h3 class="feature-title">Open Source</h3>
|
|
<p class="feature-description">Licensed under GPL v3, ensuring derivatives remain open source and accessible to everyone.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Screenshots Section -->
|
|
<section class="screenshots">
|
|
<div class="container">
|
|
<h2 class="section-title">See TimeTracker in Action</h2>
|
|
<p class="section-subtitle">Beautiful, intuitive interface designed for productivity and ease of use</p>
|
|
|
|
<div class="screenshots-grid">
|
|
<div class="screenshot-item scroll-animate">
|
|
<div class="screenshot-image">
|
|
<img src="assets/screenshots/Dashboard.png" alt="TimeTracker Dashboard - Clean interface showing active timers and recent activity" loading="lazy">
|
|
</div>
|
|
<div class="screenshot-caption">
|
|
<h3>Dashboard View</h3>
|
|
<p>Clean, intuitive interface showing active timers and recent activity. Quick access to start/stop timers and manual time entry.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="screenshot-item scroll-animate">
|
|
<div class="screenshot-image">
|
|
<img src="assets/screenshots/Projects.png" alt="TimeTracker Projects - Client and project organization with billing information" loading="lazy">
|
|
</div>
|
|
<div class="screenshot-caption">
|
|
<h3>Project Management</h3>
|
|
<p>Client and project organization with billing information. Time tracking across multiple projects simultaneously.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="screenshot-item scroll-animate">
|
|
<div class="screenshot-image">
|
|
<img src="assets/screenshots/Reports.png" alt="TimeTracker Reports - Comprehensive time reports with export capabilities" loading="lazy">
|
|
</div>
|
|
<div class="screenshot-caption">
|
|
<h3>Reports & Analytics</h3>
|
|
<p>Comprehensive time reports with export capabilities. Visual breakdowns of time allocation and productivity.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Problem & Solution Section -->
|
|
<section class="problem">
|
|
<div class="container">
|
|
<div class="problem-content">
|
|
<div class="problem-text">
|
|
<h2>Solving Real Time Tracking Problems</h2>
|
|
<ul class="problem-list">
|
|
<li>
|
|
<span class="problem-icon">❌</span>
|
|
<span>Traditional timers lose data when browsers close</span>
|
|
</li>
|
|
<li>
|
|
<span class="problem-icon">❌</span>
|
|
<span>Cloud dependencies and privacy concerns</span>
|
|
</li>
|
|
<li>
|
|
<span class="problem-icon">❌</span>
|
|
<span>Complex setup and maintenance</span>
|
|
</li>
|
|
<li>
|
|
<span class="problem-icon">❌</span>
|
|
<span>Limited reporting and export options</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="problem-visual">
|
|
<h3>TimeTracker Solutions</h3>
|
|
<p>✅ Persistent server-side timers</p>
|
|
<p>✅ Self-hosted, no cloud required</p>
|
|
<p>✅ Simple Docker deployment</p>
|
|
<p>✅ Rich reporting and exports</p>
|
|
<p>✅ Team collaboration features</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Quick Start Section -->
|
|
<section class="quick-start">
|
|
<div class="container">
|
|
<h2 class="section-title">Get Started in Minutes</h2>
|
|
<p class="section-subtitle">Deploy TimeTracker on your Raspberry Pi or any Linux system with just a few commands</p>
|
|
|
|
<div class="steps">
|
|
<div class="step scroll-animate">
|
|
<div class="step-number">1</div>
|
|
<h3 class="step-title">Clone Repository</h3>
|
|
<p class="step-description">Get the latest version of TimeTracker from GitHub</p>
|
|
<div class="code-block">
|
|
<span class="comment"># Clone the repository</span><br>
|
|
git clone https://github.com/DRYTRIX/TimeTracker.git<br>
|
|
cd TimeTracker
|
|
</div>
|
|
</div>
|
|
|
|
<div class="step scroll-animate">
|
|
<div class="step-number">2</div>
|
|
<h3 class="step-title">Configure Environment</h3>
|
|
<p class="step-description">Set up your environment variables and preferences</p>
|
|
<div class="code-block">
|
|
<span class="comment"># Copy and edit environment file</span><br>
|
|
cp .env.example .env<br>
|
|
<span class="comment"># Edit with your settings</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="step scroll-animate">
|
|
<div class="step-number">3</div>
|
|
<h3 class="step-title">Start Application</h3>
|
|
<p class="step-description">Launch TimeTracker with Docker Compose</p>
|
|
<div class="code-block">
|
|
<span class="comment"># Start the application</span><br>
|
|
docker-compose up -d
|
|
</div>
|
|
</div>
|
|
|
|
<div class="step scroll-animate">
|
|
<div class="step-number">4</div>
|
|
<h3 class="step-title">Access & Use</h3>
|
|
<p class="step-description">Open your browser and start tracking time</p>
|
|
<div class="code-block">
|
|
<span class="comment"># Access at</span><br>
|
|
<span class="string">http://your-pi-ip:8080</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Stats Section -->
|
|
<section class="stats">
|
|
<div class="container">
|
|
<div class="stats-grid">
|
|
<div class="stat-item">
|
|
<h3>100%</h3>
|
|
<p>Open Source</p>
|
|
</div>
|
|
<div class="stat-item">
|
|
<h3>0</h3>
|
|
<p>Cloud Dependencies</p>
|
|
</div>
|
|
<div class="stat-item">
|
|
<h3>∞</h3>
|
|
<p>Customization</p>
|
|
</div>
|
|
<div class="stat-item">
|
|
<h3>🚀</h3>
|
|
<p>Easy Deployment</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Footer -->
|
|
<footer class="footer">
|
|
<div class="container">
|
|
<div class="footer-content">
|
|
<div class="footer-section">
|
|
<h4>Project</h4>
|
|
<ul>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker">GitHub Repository</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/issues">Issue Tracker</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/discussions">Discussions</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/releases">Releases</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="footer-section">
|
|
<h4>Documentation</h4>
|
|
<ul>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/blob/main/README.md">README</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/blob/main/CONTRIBUTING.md">Contributing</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/blob/main/CODE_OF_CONDUCT.md">Code of Conduct</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/blob/main/LICENSE">License</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="footer-section">
|
|
<h4>Community</h4>
|
|
<ul>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/stargazers">Stars</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/network">Forks</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/graphs/contributors">Contributors</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/pulse">Activity</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="footer-section">
|
|
<h4>Support</h4>
|
|
<ul>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/issues/new">Report Bug</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/issues/new">Request Feature</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/discussions">Ask Question</a></li>
|
|
<li><a href="https://github.com/DRYTRIX/TimeTracker/wiki">Wiki</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="footer-bottom">
|
|
<p>© 2024 TimeTracker. Licensed under <a href="https://github.com/DRYTRIX/TimeTracker/blob/main/LICENSE" style="color: var(--accent-color);">GNU General Public License v3.0</a></p>
|
|
<p>Made with ❤️ for the open source community</p>
|
|
|
|
<div class="social-links">
|
|
<a href="https://github.com/DRYTRIX/TimeTracker" title="GitHub">📚</a>
|
|
<a href="https://github.com/DRYTRIX/TimeTracker/issues" title="Issues">🐛</a>
|
|
<a href="https://github.com/DRYTRIX/TimeTracker/discussions" title="Discussions">💬</a>
|
|
<a href="https://github.com/DRYTRIX/TimeTracker/stargazers" title="Stars">⭐</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<!-- JavaScript for scroll animations -->
|
|
<script>
|
|
// Scroll animation observer
|
|
const observerOptions = {
|
|
threshold: 0.1,
|
|
rootMargin: '0px 0px -50px 0px'
|
|
};
|
|
|
|
const observer = new IntersectionObserver((entries) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
entry.target.classList.add('animate');
|
|
}
|
|
});
|
|
}, observerOptions);
|
|
|
|
// Observe all scroll-animate elements
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const scrollElements = document.querySelectorAll('.scroll-animate');
|
|
scrollElements.forEach(el => observer.observe(el));
|
|
});
|
|
|
|
// Smooth scrolling for anchor links
|
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
anchor.addEventListener('click', function (e) {
|
|
e.preventDefault();
|
|
const target = document.querySelector(this.getAttribute('href'));
|
|
if (target) {
|
|
target.scrollIntoView({
|
|
behavior: 'smooth',
|
|
block: 'start'
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
// Add fade-in animation to header elements
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const headerElements = document.querySelectorAll('.header-content > *');
|
|
headerElements.forEach((el, index) => {
|
|
el.style.animationDelay = `${index * 0.2}s`;
|
|
el.classList.add('fade-in-up');
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|