Compare commits
17 Commits
v1.2.6
...
67dc5cc737
| Author | SHA1 | Date | |
|---|---|---|---|
| 67dc5cc737 | |||
| 1e377a01b0 | |||
| 6c448b336a | |||
| c6a99c7e21 | |||
| 954a1a1080 | |||
| f3a835caa2 | |||
| dee7011192 | |||
| ebd4ba649d | |||
| 9a580c77d2 | |||
| fc913b5641 | |||
| 874efd5452 | |||
| 1e8bf270a1 | |||
| d82e52ad98 | |||
| 083373a24f | |||
| 446bc7acfb | |||
| 90f0b90cc7 | |||
| ecd31f4e3b |
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"languages": {},
|
||||
"review_max_age_days": 30,
|
||||
"holistic_max_age_days": 30,
|
||||
"generate_scorecard": true,
|
||||
"badge_path": "scorecard.png",
|
||||
"exclude": [],
|
||||
"ignore": [
|
||||
"test_coverage::frontend/src/pages/Login.tsx",
|
||||
"test_coverage::frontend/src/App.tsx"
|
||||
],
|
||||
"ignore_metadata": {
|
||||
"test_coverage::frontend/src/pages/Login.tsx": {
|
||||
"note": "Login page - test coverage is separate effort, permanently ignore",
|
||||
"added_at": "2026-02-18T13:23:38+00:00"
|
||||
},
|
||||
"test_coverage::frontend/src/App.tsx": {
|
||||
"note": "Main App component - test coverage is separate effort, permanently ignore",
|
||||
"added_at": "2026-02-18T13:26:59+00:00"
|
||||
}
|
||||
},
|
||||
"zone_overrides": {},
|
||||
"review_dimensions": [],
|
||||
"review_allow_custom_dimensions": false,
|
||||
"review_custom_dimensions": [],
|
||||
"large_files_threshold": 0,
|
||||
"props_threshold": 0,
|
||||
"finding_noise_budget": 10,
|
||||
"finding_noise_global_budget": 0,
|
||||
"target_strict_score": 95
|
||||
}
|
||||
@@ -1,742 +0,0 @@
|
||||
{
|
||||
"command": "status",
|
||||
"overall_score": 75.0,
|
||||
"objective_score": 100.0,
|
||||
"strict_score": 59.3,
|
||||
"strict_all_detected": 59.1,
|
||||
"dimension_scores": {
|
||||
"File health": {
|
||||
"score": 100.0,
|
||||
"strict": 87.6,
|
||||
"checks": 143,
|
||||
"issues": 0,
|
||||
"tier": 3,
|
||||
"detectors": {
|
||||
"structural": {
|
||||
"potential": 143,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Code quality": {
|
||||
"score": 100.0,
|
||||
"strict": 67.2,
|
||||
"checks": 1211,
|
||||
"issues": 0,
|
||||
"tier": 3,
|
||||
"detectors": {
|
||||
"unused": {
|
||||
"potential": 143,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"logs": {
|
||||
"potential": 143,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"exports": {
|
||||
"potential": 305,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"deprecated": {
|
||||
"potential": 2,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"props": {
|
||||
"potential": 76,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"smells": {
|
||||
"potential": 143,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"react": {
|
||||
"potential": 14,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"orphaned": {
|
||||
"potential": 146,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"flat_dirs": {
|
||||
"potential": 25,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"naming": {
|
||||
"potential": 23,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"facade": {
|
||||
"potential": 146,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"patterns": {
|
||||
"potential": 3,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"single_use": {
|
||||
"potential": 42,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Duplication": {
|
||||
"score": 100.0,
|
||||
"strict": 99.4,
|
||||
"checks": 288,
|
||||
"issues": 0,
|
||||
"tier": 3,
|
||||
"detectors": {
|
||||
"dupes": {
|
||||
"potential": 288,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Test health": {
|
||||
"score": 100.0,
|
||||
"strict": 48.6,
|
||||
"checks": 2246,
|
||||
"issues": 0,
|
||||
"tier": 4,
|
||||
"detectors": {
|
||||
"test_coverage": {
|
||||
"potential": 2109,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"subjective_review": {
|
||||
"potential": 137,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Security": {
|
||||
"score": 100.0,
|
||||
"strict": 98.6,
|
||||
"checks": 289,
|
||||
"issues": 0,
|
||||
"tier": 4,
|
||||
"detectors": {
|
||||
"security": {
|
||||
"potential": 143,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
},
|
||||
"cycles": {
|
||||
"potential": 146,
|
||||
"pass_rate": 1.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Naming Quality": {
|
||||
"score": 0.0,
|
||||
"strict": 0.0,
|
||||
"checks": 10,
|
||||
"issues": 0,
|
||||
"tier": 4,
|
||||
"detectors": {
|
||||
"subjective_assessment": {
|
||||
"potential": 10,
|
||||
"pass_rate": 0.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 10.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Error Consistency": {
|
||||
"score": 0.0,
|
||||
"strict": 0.0,
|
||||
"checks": 10,
|
||||
"issues": 0,
|
||||
"tier": 4,
|
||||
"detectors": {
|
||||
"subjective_assessment": {
|
||||
"potential": 10,
|
||||
"pass_rate": 0.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 10.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Abstraction Fit": {
|
||||
"score": 0.0,
|
||||
"strict": 0.0,
|
||||
"checks": 10,
|
||||
"issues": 0,
|
||||
"tier": 4,
|
||||
"detectors": {
|
||||
"subjective_assessment": {
|
||||
"potential": 10,
|
||||
"pass_rate": 0.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 10.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Logic Clarity": {
|
||||
"score": 0.0,
|
||||
"strict": 0.0,
|
||||
"checks": 10,
|
||||
"issues": 0,
|
||||
"tier": 4,
|
||||
"detectors": {
|
||||
"subjective_assessment": {
|
||||
"potential": 10,
|
||||
"pass_rate": 0.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 10.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"AI Generated Debt": {
|
||||
"score": 0.0,
|
||||
"strict": 0.0,
|
||||
"checks": 10,
|
||||
"issues": 0,
|
||||
"tier": 4,
|
||||
"detectors": {
|
||||
"subjective_assessment": {
|
||||
"potential": 10,
|
||||
"pass_rate": 0.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 10.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Type Safety": {
|
||||
"score": 0.0,
|
||||
"strict": 0.0,
|
||||
"checks": 10,
|
||||
"issues": 0,
|
||||
"tier": 4,
|
||||
"detectors": {
|
||||
"subjective_assessment": {
|
||||
"potential": 10,
|
||||
"pass_rate": 0.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 10.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Contract Coherence": {
|
||||
"score": 0.0,
|
||||
"strict": 0.0,
|
||||
"checks": 10,
|
||||
"issues": 0,
|
||||
"tier": 4,
|
||||
"detectors": {
|
||||
"subjective_assessment": {
|
||||
"potential": 10,
|
||||
"pass_rate": 0.0,
|
||||
"issues": 0,
|
||||
"weighted_failures": 10.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"stats": {
|
||||
"total": 873,
|
||||
"open": 0,
|
||||
"fixed": 20,
|
||||
"auto_resolved": 1,
|
||||
"wontfix": 768,
|
||||
"false_positive": 84,
|
||||
"by_tier": {
|
||||
"1": {
|
||||
"open": 0,
|
||||
"fixed": 17,
|
||||
"auto_resolved": 0,
|
||||
"wontfix": 8,
|
||||
"false_positive": 0
|
||||
},
|
||||
"2": {
|
||||
"open": 0,
|
||||
"fixed": 3,
|
||||
"auto_resolved": 1,
|
||||
"wontfix": 376,
|
||||
"false_positive": 26
|
||||
},
|
||||
"3": {
|
||||
"open": 0,
|
||||
"fixed": 0,
|
||||
"auto_resolved": 0,
|
||||
"wontfix": 245,
|
||||
"false_positive": 58
|
||||
},
|
||||
"4": {
|
||||
"open": 0,
|
||||
"fixed": 0,
|
||||
"auto_resolved": 0,
|
||||
"wontfix": 139,
|
||||
"false_positive": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"scan_count": 10,
|
||||
"last_scan": "2026-02-18T13:28:26+00:00",
|
||||
"by_tier": {
|
||||
"1": {
|
||||
"open": 0,
|
||||
"fixed": 17,
|
||||
"auto_resolved": 0,
|
||||
"wontfix": 8,
|
||||
"false_positive": 0
|
||||
},
|
||||
"2": {
|
||||
"open": 0,
|
||||
"fixed": 3,
|
||||
"auto_resolved": 1,
|
||||
"wontfix": 376,
|
||||
"false_positive": 26
|
||||
},
|
||||
"3": {
|
||||
"open": 0,
|
||||
"fixed": 0,
|
||||
"auto_resolved": 0,
|
||||
"wontfix": 245,
|
||||
"false_positive": 58
|
||||
},
|
||||
"4": {
|
||||
"open": 0,
|
||||
"fixed": 0,
|
||||
"auto_resolved": 0,
|
||||
"wontfix": 139,
|
||||
"false_positive": 0
|
||||
}
|
||||
},
|
||||
"ignores": [
|
||||
"test_coverage::frontend/src/pages/Login.tsx",
|
||||
"test_coverage::frontend/src/App.tsx"
|
||||
],
|
||||
"suppression": {
|
||||
"last_ignored": 1,
|
||||
"last_raw_findings": 853,
|
||||
"last_suppressed_pct": 0.1,
|
||||
"last_ignore_patterns": 2,
|
||||
"recent_scans": 5,
|
||||
"recent_ignored": 1,
|
||||
"recent_raw_findings": 4265,
|
||||
"recent_suppressed_pct": 0.0
|
||||
},
|
||||
"detector_transparency": {
|
||||
"rows": [
|
||||
{
|
||||
"detector": "exports",
|
||||
"visible": 305,
|
||||
"suppressed": 0,
|
||||
"excluded": 0,
|
||||
"total_detected": 305
|
||||
},
|
||||
{
|
||||
"detector": "smells",
|
||||
"visible": 215,
|
||||
"suppressed": 0,
|
||||
"excluded": 1,
|
||||
"total_detected": 216
|
||||
},
|
||||
{
|
||||
"detector": "subjective_review",
|
||||
"visible": 138,
|
||||
"suppressed": 0,
|
||||
"excluded": 0,
|
||||
"total_detected": 138
|
||||
},
|
||||
{
|
||||
"detector": "test_coverage",
|
||||
"visible": 49,
|
||||
"suppressed": 1,
|
||||
"excluded": 0,
|
||||
"total_detected": 50
|
||||
},
|
||||
{
|
||||
"detector": "structural",
|
||||
"visible": 25,
|
||||
"suppressed": 0,
|
||||
"excluded": 0,
|
||||
"total_detected": 25
|
||||
},
|
||||
{
|
||||
"detector": "security",
|
||||
"visible": 18,
|
||||
"suppressed": 0,
|
||||
"excluded": 0,
|
||||
"total_detected": 18
|
||||
},
|
||||
{
|
||||
"detector": "logs",
|
||||
"visible": 6,
|
||||
"suppressed": 0,
|
||||
"excluded": 0,
|
||||
"total_detected": 6
|
||||
},
|
||||
{
|
||||
"detector": "dupes",
|
||||
"visible": 3,
|
||||
"suppressed": 0,
|
||||
"excluded": 0,
|
||||
"total_detected": 3
|
||||
},
|
||||
{
|
||||
"detector": "deprecated",
|
||||
"visible": 0,
|
||||
"suppressed": 0,
|
||||
"excluded": 2,
|
||||
"total_detected": 2
|
||||
},
|
||||
{
|
||||
"detector": "flat_dirs",
|
||||
"visible": 2,
|
||||
"suppressed": 0,
|
||||
"excluded": 0,
|
||||
"total_detected": 2
|
||||
},
|
||||
{
|
||||
"detector": "unused",
|
||||
"visible": 2,
|
||||
"suppressed": 0,
|
||||
"excluded": 0,
|
||||
"total_detected": 2
|
||||
},
|
||||
{
|
||||
"detector": "cycles",
|
||||
"visible": 1,
|
||||
"suppressed": 0,
|
||||
"excluded": 0,
|
||||
"total_detected": 1
|
||||
},
|
||||
{
|
||||
"detector": "react",
|
||||
"visible": 1,
|
||||
"suppressed": 0,
|
||||
"excluded": 0,
|
||||
"total_detected": 1
|
||||
}
|
||||
],
|
||||
"totals": {
|
||||
"visible": 765,
|
||||
"suppressed": 1,
|
||||
"excluded": 3,
|
||||
"detectors": 13
|
||||
}
|
||||
},
|
||||
"potentials": {
|
||||
"typescript": {
|
||||
"logs": 143,
|
||||
"unused": 143,
|
||||
"exports": 305,
|
||||
"deprecated": 2,
|
||||
"structural": 143,
|
||||
"flat_dirs": 25,
|
||||
"props": 76,
|
||||
"single_use": 42,
|
||||
"coupling": 0,
|
||||
"cycles": 146,
|
||||
"orphaned": 146,
|
||||
"patterns": 3,
|
||||
"naming": 23,
|
||||
"facade": 146,
|
||||
"test_coverage": 2109,
|
||||
"smells": 143,
|
||||
"react": 14,
|
||||
"security": 143,
|
||||
"subjective_review": 137,
|
||||
"dupes": 288
|
||||
}
|
||||
},
|
||||
"codebase_metrics": {
|
||||
"typescript": {
|
||||
"total_files": 151,
|
||||
"total_loc": 40054,
|
||||
"total_directories": 25
|
||||
}
|
||||
},
|
||||
"strict_target": {
|
||||
"target": 95.0,
|
||||
"current": 59.3,
|
||||
"gap": 35.7,
|
||||
"state": "below",
|
||||
"warning": null
|
||||
},
|
||||
"narrative": {
|
||||
"phase": "stagnation",
|
||||
"headline": "All T1 and T2 items cleared!",
|
||||
"dimensions": {
|
||||
"lowest_dimensions": [
|
||||
{
|
||||
"name": "Naming Quality",
|
||||
"strict": 0.0,
|
||||
"issues": 0,
|
||||
"impact": 0.0,
|
||||
"subjective": true,
|
||||
"impact_description": "re-review to improve"
|
||||
},
|
||||
{
|
||||
"name": "Error Consistency",
|
||||
"strict": 0.0,
|
||||
"issues": 0,
|
||||
"impact": 0.0,
|
||||
"subjective": true,
|
||||
"impact_description": "re-review to improve"
|
||||
},
|
||||
{
|
||||
"name": "Abstraction Fit",
|
||||
"strict": 0.0,
|
||||
"issues": 0,
|
||||
"impact": 0.0,
|
||||
"subjective": true,
|
||||
"impact_description": "re-review to improve"
|
||||
}
|
||||
],
|
||||
"biggest_gap_dimensions": [
|
||||
{
|
||||
"name": "Test health",
|
||||
"lenient": 100.0,
|
||||
"strict": 48.6,
|
||||
"gap": 51.4,
|
||||
"wontfix_count": 187
|
||||
},
|
||||
{
|
||||
"name": "Code quality",
|
||||
"lenient": 100.0,
|
||||
"strict": 67.2,
|
||||
"gap": 32.8,
|
||||
"wontfix_count": 534
|
||||
},
|
||||
{
|
||||
"name": "File health",
|
||||
"lenient": 100.0,
|
||||
"strict": 87.6,
|
||||
"gap": 12.4,
|
||||
"wontfix_count": 25
|
||||
}
|
||||
],
|
||||
"stagnant_dimensions": [
|
||||
{
|
||||
"name": "File health",
|
||||
"strict": 87.6,
|
||||
"stuck_scans": 5
|
||||
},
|
||||
{
|
||||
"name": "Code quality",
|
||||
"strict": 67.2,
|
||||
"stuck_scans": 5
|
||||
},
|
||||
{
|
||||
"name": "Duplication",
|
||||
"strict": 99.4,
|
||||
"stuck_scans": 5
|
||||
},
|
||||
{
|
||||
"name": "Security",
|
||||
"strict": 98.6,
|
||||
"stuck_scans": 5
|
||||
},
|
||||
{
|
||||
"name": "Naming Quality",
|
||||
"strict": 0.0,
|
||||
"stuck_scans": 5
|
||||
},
|
||||
{
|
||||
"name": "Error Consistency",
|
||||
"strict": 0.0,
|
||||
"stuck_scans": 5
|
||||
},
|
||||
{
|
||||
"name": "Abstraction Fit",
|
||||
"strict": 0.0,
|
||||
"stuck_scans": 5
|
||||
},
|
||||
{
|
||||
"name": "Logic Clarity",
|
||||
"strict": 0.0,
|
||||
"stuck_scans": 5
|
||||
},
|
||||
{
|
||||
"name": "AI Generated Debt",
|
||||
"strict": 0.0,
|
||||
"stuck_scans": 5
|
||||
},
|
||||
{
|
||||
"name": "Type Safety",
|
||||
"strict": 0.0,
|
||||
"stuck_scans": 5
|
||||
},
|
||||
{
|
||||
"name": "Contract Coherence",
|
||||
"strict": 0.0,
|
||||
"stuck_scans": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
"actions": [
|
||||
{
|
||||
"priority": 1,
|
||||
"type": "debt_review",
|
||||
"detector": null,
|
||||
"description": "7.8 pts of wontfix debt \u2014 review stale decisions",
|
||||
"command": "desloppify show --status wontfix",
|
||||
"gap": 7.8,
|
||||
"lane": "debt_review"
|
||||
}
|
||||
],
|
||||
"strategy": {
|
||||
"fixer_leverage": {
|
||||
"auto_fixable_count": 0,
|
||||
"total_count": 0,
|
||||
"coverage": 0.0,
|
||||
"impact_ratio": 0.0,
|
||||
"recommendation": "none"
|
||||
},
|
||||
"lanes": {
|
||||
"debt_review": {
|
||||
"actions": [
|
||||
1
|
||||
],
|
||||
"file_count": 0,
|
||||
"total_impact": 0.0,
|
||||
"automation": "manual",
|
||||
"run_first": false
|
||||
}
|
||||
},
|
||||
"can_parallelize": false,
|
||||
"hint": "Try a different dimension to break the plateau."
|
||||
},
|
||||
"tools": {
|
||||
"fixers": [],
|
||||
"move": {
|
||||
"available": true,
|
||||
"relevant": false,
|
||||
"reason": null,
|
||||
"usage": "desloppify move <source> <dest> [--dry-run]"
|
||||
},
|
||||
"plan": {
|
||||
"command": "desloppify plan",
|
||||
"description": "Generate prioritized markdown cleanup plan"
|
||||
},
|
||||
"badge": {
|
||||
"generated": true,
|
||||
"in_readme": true,
|
||||
"path": "scorecard.png",
|
||||
"recommendation": null
|
||||
}
|
||||
},
|
||||
"debt": {
|
||||
"overall_gap": 7.8,
|
||||
"wontfix_count": 768,
|
||||
"worst_dimension": "Test health",
|
||||
"worst_gap": 51.4,
|
||||
"trend": "stable"
|
||||
},
|
||||
"milestone": "All T1 and T2 items cleared!",
|
||||
"primary_action": {
|
||||
"priority": 1,
|
||||
"type": "debt_review",
|
||||
"detector": null,
|
||||
"command": "desloppify show --status wontfix",
|
||||
"description": "7.8 pts of wontfix debt \u2014 review stale decisions",
|
||||
"impact": null,
|
||||
"lane": "debt_review",
|
||||
"count": null
|
||||
},
|
||||
"why_now": "Progress is plateaued, so the top action is the best chance to break the plateau.",
|
||||
"verification_step": {
|
||||
"command": "desloppify show --status wontfix",
|
||||
"reason": "Re-check stale wontfix decisions before treating strict score as stable.",
|
||||
"success_signal": "Wontfix list reflects only intentional and still-valid exceptions."
|
||||
},
|
||||
"risk_flags": [
|
||||
{
|
||||
"type": "wontfix_gap",
|
||||
"severity": "medium",
|
||||
"message": "7.8 strict-score points are masked by wontfix debt (768 items).",
|
||||
"command": "desloppify show --status wontfix"
|
||||
}
|
||||
],
|
||||
"strict_target": {
|
||||
"target": 95.0,
|
||||
"current": 59.3,
|
||||
"gap": 35.7,
|
||||
"state": "below",
|
||||
"warning": null
|
||||
},
|
||||
"reminders": [],
|
||||
"reminder_history": {
|
||||
"report_scores": 10,
|
||||
"auto_fixers_available": 3,
|
||||
"dry_run_first": 3,
|
||||
"zone_classification": 3,
|
||||
"feedback_nudge": 3,
|
||||
"stagnant_nudge": 10,
|
||||
"fp_calibration_security_production": 3,
|
||||
"wontfix_growing": 3,
|
||||
"fp_calibration_orphaned_production": 3
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"review_max_age_days": 30,
|
||||
"holistic_max_age_days": 30,
|
||||
"generate_scorecard": true,
|
||||
"badge_path": "scorecard.png",
|
||||
"exclude": [],
|
||||
"ignore": [
|
||||
"test_coverage::frontend/src/pages/Login.tsx",
|
||||
"test_coverage::frontend/src/App.tsx"
|
||||
],
|
||||
"ignore_metadata": {
|
||||
"test_coverage::frontend/src/pages/Login.tsx": {
|
||||
"note": "Login page - test coverage is separate effort, permanently ignore",
|
||||
"added_at": "2026-02-18T13:23:38+00:00"
|
||||
},
|
||||
"test_coverage::frontend/src/App.tsx": {
|
||||
"note": "Main App component - test coverage is separate effort, permanently ignore",
|
||||
"added_at": "2026-02-18T13:26:59+00:00"
|
||||
}
|
||||
},
|
||||
"zone_overrides": {},
|
||||
"review_dimensions": [],
|
||||
"review_allow_custom_dimensions": false,
|
||||
"review_custom_dimensions": [],
|
||||
"large_files_threshold": 0,
|
||||
"props_threshold": 0,
|
||||
"finding_noise_budget": 10,
|
||||
"finding_noise_global_budget": 0,
|
||||
"target_strict_score": 95,
|
||||
"languages": {}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ node_modules
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
.env
|
||||
.env.local
|
||||
.env.production
|
||||
Dockerfile
|
||||
|
||||
@@ -1,112 +1,13 @@
|
||||
# Server Configuration
|
||||
PORT=8080
|
||||
GIN_MODE=debug
|
||||
READ_TIMEOUT=15s
|
||||
WRITE_TIMEOUT=15s
|
||||
IDLE_TIMEOUT=60s
|
||||
SHUTDOWN_TIMEOUT=30s
|
||||
# Trackeep Configuration for Casa OS
|
||||
# Only required variables - everything else is auto-configured
|
||||
|
||||
# Host port for the application (default: 8080)
|
||||
HOST_PORT=8080
|
||||
|
||||
# Database Configuration
|
||||
DB_TYPE=postgres
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_PASSWORD=your_secure_password_here
|
||||
DB_USER=trackeep
|
||||
DB_PASSWORD=your_password_here
|
||||
DB_NAME=trackeep
|
||||
DB_SSL_MODE=disable
|
||||
|
||||
# Docker Compose Database (used by docker-compose.yml)
|
||||
POSTGRES_DB=trackeep
|
||||
POSTGRES_USER=trackeep
|
||||
POSTGRES_PASSWORD=your_secure_password_here
|
||||
|
||||
# JWT Configuration
|
||||
# JWT_SECRET is auto-generated on startup and stored in jwt_secret.key
|
||||
# You can override by setting JWT_SECRET environment variable if needed
|
||||
JWT_EXPIRES_IN=24h
|
||||
|
||||
# Encryption Configuration
|
||||
# ENCRYPTION_KEY is auto-generated on startup and stored in encryption.key
|
||||
# You can override by setting ENCRYPTION_KEY environment variable if needed
|
||||
|
||||
# File Upload Configuration
|
||||
UPLOAD_DIR=./uploads
|
||||
MAX_FILE_SIZE=10485760
|
||||
|
||||
# CORS Configuration
|
||||
CORS_ALLOWED_ORIGINS=*
|
||||
|
||||
# AI Services Configuration
|
||||
LONGCAT_ON=false
|
||||
LONGCAT_API_KEY=your_longcat_api_key_here
|
||||
LONGCAT_BASE_URL=https://api.longcat.chat
|
||||
LONGCAT_OPENAI_ENDPOINT=https://api.longcat.chat/openai
|
||||
LONGCAT_ANTHROPIC_ENDPOINT=https://api.longcat.chat/anthropic
|
||||
LONGCAT_MODEL=LongCat-Flash-Chat
|
||||
LONGCAT_MODEL_THINKING=LongCat-Flash-Thinking
|
||||
LONGCAT_FORMAT=openai
|
||||
|
||||
# Mistral AI Configuration
|
||||
MISTRAL_ON=false
|
||||
MISTRAL_API_KEY=your_mistral_api_key_here
|
||||
MISTRAL_MODEL=mistral-small-latest
|
||||
MISTRAL_MODEL_THINKING=mistral-large-latest
|
||||
|
||||
# Grok AI Configuration
|
||||
GROK_ON=false
|
||||
GROK_API_KEY=your_grok_api_key_here
|
||||
GROK_BASE_URL=https://api.x.ai/v1
|
||||
GROK_MODEL=grok-4-1-fast-non-reasoning-latest
|
||||
GROK_MODEL_THINKING=grok-4-1-fast-reasoning-latest
|
||||
|
||||
# DeepSeek Configuration
|
||||
DEEPSEEK_ON=false
|
||||
DEEPSEEK_API_KEY=your_deepseek_api_key_here
|
||||
DEEPSEEK_BASE_URL=https://api.deepseek.com
|
||||
DEEPSEEK_MODEL=deepseek-chat
|
||||
DEEPSEEK_MODEL_THINKING=deepseek-reasoner
|
||||
|
||||
# Ollama Configuration
|
||||
OLLAMA_ON=false
|
||||
OLLAMA_BASE_URL=http://localhost:11434
|
||||
OLLAMA_MODEL=llama3.1
|
||||
OLLAMA_MODEL_THINKING=llama3.1
|
||||
|
||||
# OpenRouter Configuration
|
||||
OPENROUTER_ON=false
|
||||
OPENROUTER_API_KEY=your_openrouter_api_key_here
|
||||
OPENROUTER_BASE_URL=https://openrouter.ai/api
|
||||
OPENROUTER_MODEL=openrouter/auto
|
||||
OPENROUTER_MODEL_THINKING=openrouter/auto
|
||||
|
||||
# Demo Mode Configuration
|
||||
VITE_DEMO_MODE=false
|
||||
|
||||
# Browser Search API Configuration
|
||||
BRAVE_API_KEY=your_brave_api_key_here
|
||||
BRAVE_SEARCH_BASE_URL=https://api.search.brave.com/res/v1/web/search
|
||||
SERPER_API_KEY=your_serper_api_key_here
|
||||
SERPER_BASE_URL=https://google.serper.dev/search
|
||||
SEARCH_API_PROVIDER=brave # Options: brave, serper, demo
|
||||
|
||||
# Search Configuration
|
||||
SEARCH_RESULTS_LIMIT=10
|
||||
SEARCH_CACHE_TTL=300
|
||||
SEARCH_RATE_LIMIT=100
|
||||
|
||||
# Update Configuration
|
||||
# Application version (used for update checking)
|
||||
APP_VERSION=1.0.0
|
||||
|
||||
# OAuth service configuration (REQUIRED)
|
||||
# The OAuth service must be running for updates to work
|
||||
OAUTH_SERVICE_URL=http://localhost:9090
|
||||
JWT_SECRET=your-jwt-secret-key
|
||||
|
||||
# Update settings
|
||||
AUTO_UPDATE_CHECK=false
|
||||
UPDATE_CHECK_INTERVAL=24h
|
||||
PRERELEASE_UPDATES=false
|
||||
|
||||
# Note: No GitHub token configuration needed
|
||||
# Updates use the OAuth service which handles GitHub authentication automatically
|
||||
# JWT Secret (generate with: openssl rand -hex 32)
|
||||
JWT_SECRET=your_jwt_secret_here_64_hex_characters_long_exactly
|
||||
|
||||
@@ -36,7 +36,9 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.24'
|
||||
go-version: '1.25'
|
||||
cache: true
|
||||
cache-dependency-path: backend/go.sum
|
||||
|
||||
- name: Install backend dependencies
|
||||
run: |
|
||||
@@ -90,7 +92,9 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.24'
|
||||
go-version: '1.25'
|
||||
cache: true
|
||||
cache-dependency-path: backend/go.sum
|
||||
|
||||
- name: Run go vet
|
||||
run: |
|
||||
@@ -124,43 +128,23 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta-backend
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/backend
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=sha,prefix={{branch}}-
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta-frontend
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/frontend
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=sha,prefix={{branch}}-
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push backend image
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: ./backend
|
||||
push: true
|
||||
tags: ${{ steps.meta-backend.outputs.tags }}
|
||||
labels: ${{ steps.meta-backend.outputs.labels }}
|
||||
|
||||
- name: Build and push frontend image
|
||||
- name: Build and push unified image
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
file: ./frontend/Dockerfile
|
||||
push: true
|
||||
tags: ${{ steps.meta-frontend.outputs.tags }}
|
||||
labels: ${{ steps.meta-frontend.outputs.labels }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
# deploy:
|
||||
# name: Deploy to Production
|
||||
|
||||
@@ -37,9 +37,6 @@ jobs:
|
||||
build-and-push:
|
||||
needs: extract-version
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
service: [backend, frontend]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -57,7 +54,7 @@ jobs:
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ matrix.service }}
|
||||
images: ${{ env.REGISTRY }}
|
||||
tags: |
|
||||
type=ref,event=tag
|
||||
type=semver,pattern={{version}}
|
||||
@@ -66,18 +63,12 @@ jobs:
|
||||
version=${{ needs.extract-version.outputs.version }}
|
||||
build-date=${{ github.event.head_commit.timestamp }}
|
||||
commit=${{ github.sha }}
|
||||
service=${{ matrix.service }}
|
||||
prerelease=${{ needs.extract-version.outputs.is-prerelease }}
|
||||
|
||||
- name: Build and push ${{ matrix.service }}
|
||||
- name: Build and push unified image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: |
|
||||
backend=./backend
|
||||
frontend=.
|
||||
file: |
|
||||
backend=./backend/Dockerfile
|
||||
frontend=./frontend/Dockerfile
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
@@ -87,15 +78,15 @@ jobs:
|
||||
- name: Generate SBOM
|
||||
uses: anchore/sbom-action@v0
|
||||
with:
|
||||
image: ${{ env.REGISTRY }}/${{ matrix.service }}:${{ needs.extract-version.outputs.version }}
|
||||
image: ${{ env.REGISTRY }}:${{ needs.extract-version.outputs.version }}
|
||||
format: spdx-json
|
||||
output-file: ./sbom-${{ matrix.service }}.spdx.json
|
||||
output-file: ./sbom.spdx.json
|
||||
|
||||
- name: Upload SBOM
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sbom-${{ matrix.service }}
|
||||
path: ./sbom-${{ matrix.service }}.spdx.json
|
||||
name: sbom
|
||||
path: ./sbom.spdx.json
|
||||
|
||||
create-github-release:
|
||||
needs: [extract-version, build-and-push]
|
||||
@@ -107,26 +98,21 @@ jobs:
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag: v${{ needs.extract-version.outputs.version }}
|
||||
name: Trackeep v${{ needs.extract-version.outputs.version }}
|
||||
body: |
|
||||
## 🚀 Trackeep v${{ needs.extract-version.outputs.version }}
|
||||
|
||||
### 🐳 Docker Images
|
||||
- **Backend**: `ghcr.io/dvorinka/trackeep/backend:${{ needs.extract-version.outputs.version }}`
|
||||
- **Frontend**: `ghcr.io/dvorinka/trackeep/frontend:${{ needs.extract-version.outputs.version }}`
|
||||
- **Latest**: `ghcr.io/dvorinka/trackeep/backend:latest` and `ghcr.io/dvorinka/trackeep/frontend:latest`
|
||||
### 🐳 Docker Image
|
||||
- **Unified**: `ghcr.io/dvorinka/trackeep:${{ needs.extract-version.outputs.version }}`
|
||||
- **Latest**: `ghcr.io/dvorinka/trackeep:latest`
|
||||
|
||||
### 📋 Changes
|
||||
${{ github.event.head_commit.message }}
|
||||
|
||||
### 🔧 Installation
|
||||
```bash
|
||||
# Set version
|
||||
export APP_VERSION=${{ needs.extract-version.outputs.version }}
|
||||
|
||||
# Deploy with production compose
|
||||
docker compose -f docker-compose.prod.yml up -d
|
||||
# Deploy with docker compose
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### ⚡ Auto-Updates
|
||||
@@ -138,12 +124,10 @@ jobs:
|
||||
|
||||
draft: false
|
||||
prerelease: ${{ needs.extract-version.outputs.is-prerelease }}
|
||||
files: |
|
||||
sbom-backend.spdx.json
|
||||
sbom-frontend.spdx.json
|
||||
files: sbom.spdx.json
|
||||
generate_release_notes: true
|
||||
|
||||
update-docker-compose-prod:
|
||||
update-version-files:
|
||||
needs: extract-version
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -168,17 +152,6 @@ jobs:
|
||||
echo "✅ Backend updated to $VERSION"
|
||||
fi
|
||||
|
||||
# Update docker-compose files
|
||||
if [ -f "docker-compose.yml" ]; then
|
||||
sed -i "s/APP_VERSION=.*/APP_VERSION=$VERSION/" docker-compose.yml
|
||||
echo "✅ docker-compose.yml updated"
|
||||
fi
|
||||
|
||||
if [ -f "docker-compose.prod.yml" ]; then
|
||||
sed -i "s/APP_VERSION=.*/APP_VERSION=$VERSION/" docker-compose.prod.yml
|
||||
echo "✅ docker-compose.prod.yml updated"
|
||||
fi
|
||||
|
||||
echo "🎉 All version files updated to $VERSION"
|
||||
|
||||
- name: Commit updated version files
|
||||
|
||||
@@ -26,6 +26,9 @@ pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
.playwright
|
||||
.playwright-cli
|
||||
.desloppify
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage/
|
||||
@@ -83,7 +86,7 @@ dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
public
|
||||
/public
|
||||
|
||||
# Storybook build outputs
|
||||
.out
|
||||
@@ -177,7 +180,7 @@ dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
public
|
||||
/public
|
||||
|
||||
# Storybook build outputs
|
||||
.out
|
||||
@@ -256,6 +259,10 @@ Thumbs.db
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
# Desktop app build artifacts
|
||||
desktop/dist/
|
||||
desktop/src-tauri/target/
|
||||
|
||||
# Lock files (keep package-lock.json but ignore yarn.lock if using npm)
|
||||
# yarn.lock
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,18 +0,0 @@
|
||||
- generic [ref=e26]:
|
||||
- generic [ref=e27]:
|
||||
- img "Trackeep Logo" [ref=e29]
|
||||
- heading "Trackeep" [level=1] [ref=e30]
|
||||
- paragraph [ref=e31]: Welcome back
|
||||
- generic [ref=e32]:
|
||||
- generic [ref=e35]: Registration Disabled
|
||||
- paragraph [ref=e36]: Accounts can only be created by the administrator. Please contact your admin to get an account.
|
||||
- generic [ref=e37]:
|
||||
- generic [ref=e38]:
|
||||
- generic [ref=e39]: Email
|
||||
- textbox "Email" [ref=e40]:
|
||||
- /placeholder: your@email.com
|
||||
- generic [ref=e41]:
|
||||
- generic [ref=e42]: Password
|
||||
- textbox "Password" [ref=e43]:
|
||||
- /placeholder: ••••••••
|
||||
- button "Sign In" [ref=e44] [cursor=pointer]
|
||||
@@ -1,21 +0,0 @@
|
||||
- generic [ref=e26]:
|
||||
- generic [ref=e27]:
|
||||
- img "Trackeep Logo" [ref=e29]
|
||||
- heading "Trackeep" [level=1] [ref=e30]
|
||||
- paragraph [ref=e31]: Welcome back
|
||||
- generic [ref=e32]:
|
||||
- generic [ref=e35]: Registration Disabled
|
||||
- paragraph [ref=e36]: Accounts can only be created by the administrator. Please contact your admin to get an account.
|
||||
- generic [ref=e37]:
|
||||
- generic [ref=e45]: Invalid credentials
|
||||
- generic [ref=e38]:
|
||||
- generic [ref=e39]: Email
|
||||
- textbox "Email" [ref=e40]:
|
||||
- /placeholder: your@email.com
|
||||
- text: demo@trackeep.com
|
||||
- generic [ref=e41]:
|
||||
- generic [ref=e42]: Password
|
||||
- textbox "Password" [ref=e43]:
|
||||
- /placeholder: ••••••••
|
||||
- text: password
|
||||
- button "Sign In" [ref=e44] [cursor=pointer]
|
||||
@@ -1 +0,0 @@
|
||||
- paragraph [ref=e6]: Checking authentication...
|
||||
@@ -1 +0,0 @@
|
||||
- paragraph [ref=e6]: Checking authentication...
|
||||
@@ -1 +0,0 @@
|
||||
- paragraph [ref=e6]: Checking authentication...
|
||||
@@ -1 +0,0 @@
|
||||
- paragraph [ref=e6]: Checking authentication...
|
||||
@@ -1 +0,0 @@
|
||||
- paragraph [ref=e6]: Checking authentication...
|
||||
@@ -1 +0,0 @@
|
||||
- paragraph [ref=e6]: Checking authentication...
|
||||
@@ -1 +0,0 @@
|
||||
- paragraph [ref=e6]: Checking authentication...
|
||||
@@ -1 +0,0 @@
|
||||
- paragraph [ref=e6]: Checking authentication...
|
||||
@@ -1 +0,0 @@
|
||||
- paragraph [ref=e6]: Checking authentication...
|
||||
@@ -1 +0,0 @@
|
||||
- paragraph [ref=e6]: Checking authentication...
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,18 +0,0 @@
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e5]:
|
||||
- img "Trackeep Logo" [ref=e7]
|
||||
- heading "Trackeep" [level=1] [ref=e8]
|
||||
- paragraph [ref=e9]: Welcome back
|
||||
- generic [ref=e10]:
|
||||
- generic [ref=e13]: Registration Disabled
|
||||
- paragraph [ref=e14]: Accounts can only be created by the administrator. Please contact your admin to get an account.
|
||||
- generic [ref=e15]:
|
||||
- generic [ref=e16]:
|
||||
- generic [ref=e17]: Email
|
||||
- textbox "Email" [ref=e18]:
|
||||
- /placeholder: your@email.com
|
||||
- generic [ref=e19]:
|
||||
- generic [ref=e20]: Password
|
||||
- textbox "Password" [ref=e21]:
|
||||
- /placeholder: ••••••••
|
||||
- button "Sign In" [ref=e22] [cursor=pointer]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,18 +0,0 @@
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e5]:
|
||||
- img "Trackeep Logo" [ref=e7]
|
||||
- heading "Trackeep" [level=1] [ref=e8]
|
||||
- paragraph [ref=e9]: Welcome back
|
||||
- generic [ref=e10]:
|
||||
- generic [ref=e13]: Registration Disabled
|
||||
- paragraph [ref=e14]: Accounts can only be created by the administrator. Please contact your admin to get an account.
|
||||
- generic [ref=e15]:
|
||||
- generic [ref=e16]:
|
||||
- generic [ref=e17]: Email
|
||||
- textbox "Email" [ref=e18]:
|
||||
- /placeholder: your@email.com
|
||||
- generic [ref=e19]:
|
||||
- generic [ref=e20]: Password
|
||||
- textbox "Password" [ref=e21]:
|
||||
- /placeholder: ••••••••
|
||||
- button "Sign In" [ref=e22] [cursor=pointer]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,237 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:21 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,237 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:21 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,237 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:22 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,257 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:22 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
- generic [ref=e279]:
|
||||
- generic [ref=e280]:
|
||||
- heading "Create Workspace" [level=3] [ref=e281]
|
||||
- paragraph [ref=e282]: Add a new workspace for your team or projects.
|
||||
- generic [ref=e283]:
|
||||
- generic [ref=e284]:
|
||||
- text: Name
|
||||
- textbox "Workspace name" [ref=e285]
|
||||
- generic [ref=e286]:
|
||||
- text: Description
|
||||
- textbox "Description" [ref=e287]:
|
||||
- /placeholder: Optional description
|
||||
- generic [ref=e288]:
|
||||
- generic [ref=e289]:
|
||||
- paragraph [ref=e290]: Public workspace
|
||||
- paragraph [ref=e291]: Allow all members to discover this workspace.
|
||||
- switch [ref=e292] [cursor=pointer]
|
||||
- generic [ref=e293]:
|
||||
- button "Cancel" [ref=e294] [cursor=pointer]
|
||||
- button "Create Workspace" [ref=e295] [cursor=pointer]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,237 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:22 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,244 +0,0 @@
|
||||
- generic [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [expanded] [active] [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- listbox [ref=e266]:
|
||||
- option "Trackeep Workspace" [ref=e267] [cursor=pointer]:
|
||||
- img [ref=e268]
|
||||
- generic [ref=e271]: Trackeep Workspace
|
||||
- button "Create Workspace" [ref=e274] [cursor=pointer]:
|
||||
- img [ref=e275]
|
||||
- generic [ref=e276]: Create Workspace
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:22 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,244 +0,0 @@
|
||||
- generic [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [expanded] [active] [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- listbox [ref=e266]:
|
||||
- option "Trackeep Workspace" [ref=e267] [cursor=pointer]:
|
||||
- img [ref=e268]
|
||||
- generic [ref=e271]: Trackeep Workspace
|
||||
- button "Create Workspace" [ref=e274] [cursor=pointer]:
|
||||
- img [ref=e275]
|
||||
- generic [ref=e276]: Create Workspace
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:22 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,237 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:23 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,244 +0,0 @@
|
||||
- generic [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [expanded] [active] [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- listbox [ref=e266]:
|
||||
- option "Trackeep Workspace" [ref=e267] [cursor=pointer]:
|
||||
- img [ref=e268]
|
||||
- generic [ref=e271]: Trackeep Workspace
|
||||
- button "Create Workspace" [ref=e274] [cursor=pointer]:
|
||||
- img [ref=e275]
|
||||
- generic [ref=e276]: Create Workspace
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:23 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,257 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:23 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
- generic [ref=e279]:
|
||||
- generic [ref=e280]:
|
||||
- heading "Create Workspace" [level=3] [ref=e281]
|
||||
- paragraph [ref=e282]: Add a new workspace for your team or projects.
|
||||
- generic [ref=e283]:
|
||||
- generic [ref=e284]:
|
||||
- text: Name
|
||||
- textbox "Workspace name" [ref=e285]
|
||||
- generic [ref=e286]:
|
||||
- text: Description
|
||||
- textbox "Description" [ref=e287]:
|
||||
- /placeholder: Optional description
|
||||
- generic [ref=e288]:
|
||||
- generic [ref=e289]:
|
||||
- paragraph [ref=e290]: Public workspace
|
||||
- paragraph [ref=e291]: Allow all members to discover this workspace.
|
||||
- switch [ref=e292] [cursor=pointer]
|
||||
- generic [ref=e293]:
|
||||
- button "Cancel" [ref=e294] [cursor=pointer]
|
||||
- button "Create Workspace" [ref=e295] [cursor=pointer]
|
||||
@@ -1,257 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:23 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
- generic [ref=e279]:
|
||||
- generic [ref=e280]:
|
||||
- heading "Create Workspace" [level=3] [ref=e281]
|
||||
- paragraph [ref=e282]: Add a new workspace for your team or projects.
|
||||
- generic [ref=e283]:
|
||||
- generic [ref=e284]:
|
||||
- text: Name
|
||||
- textbox "Workspace name" [ref=e285]
|
||||
- generic [ref=e286]:
|
||||
- text: Description
|
||||
- textbox "Description" [ref=e287]:
|
||||
- /placeholder: Optional description
|
||||
- generic [ref=e288]:
|
||||
- generic [ref=e289]:
|
||||
- paragraph [ref=e290]: Public workspace
|
||||
- paragraph [ref=e291]: Allow all members to discover this workspace.
|
||||
- switch [ref=e292] [cursor=pointer]
|
||||
- generic [ref=e293]:
|
||||
- button "Cancel" [ref=e294] [cursor=pointer]
|
||||
- button "Create Workspace" [ref=e295] [cursor=pointer]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,237 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:23 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,263 +0,0 @@
|
||||
- generic [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- generic [ref=e178]:
|
||||
- button "AU" [active] [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- generic [ref=e267]:
|
||||
- generic [ref=e269]:
|
||||
- generic [ref=e270]: AU
|
||||
- generic [ref=e271]:
|
||||
- paragraph [ref=e272]: Admin User
|
||||
- paragraph [ref=e273]: admin@trackeep.com
|
||||
- generic [ref=e275]:
|
||||
- generic [ref=e276]:
|
||||
- paragraph [ref=e277]: "0"
|
||||
- paragraph [ref=e278]: Bookmarks
|
||||
- generic [ref=e279]:
|
||||
- paragraph [ref=e280]: "0"
|
||||
- paragraph [ref=e281]: Tasks
|
||||
- button "Profile" [ref=e282] [cursor=pointer]:
|
||||
- img [ref=e283]
|
||||
- text: Profile
|
||||
- button "Statistics" [ref=e286] [cursor=pointer]:
|
||||
- img [ref=e287]
|
||||
- text: Statistics
|
||||
- button "Settings" [ref=e289] [cursor=pointer]:
|
||||
- img [ref=e290]
|
||||
- text: Settings
|
||||
- button "Logout" [ref=e294] [cursor=pointer]:
|
||||
- img [ref=e295]
|
||||
- text: Logout
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:23 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,263 +0,0 @@
|
||||
- generic [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- generic [ref=e178]:
|
||||
- button "AU" [active] [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- generic [ref=e267]:
|
||||
- generic [ref=e269]:
|
||||
- generic [ref=e270]: AU
|
||||
- generic [ref=e271]:
|
||||
- paragraph [ref=e272]: Admin User
|
||||
- paragraph [ref=e273]: admin@trackeep.com
|
||||
- generic [ref=e275]:
|
||||
- generic [ref=e276]:
|
||||
- paragraph [ref=e277]: "0"
|
||||
- paragraph [ref=e278]: Bookmarks
|
||||
- generic [ref=e279]:
|
||||
- paragraph [ref=e280]: "0"
|
||||
- paragraph [ref=e281]: Tasks
|
||||
- button "Profile" [ref=e282] [cursor=pointer]:
|
||||
- img [ref=e283]
|
||||
- text: Profile
|
||||
- button "Statistics" [ref=e286] [cursor=pointer]:
|
||||
- img [ref=e287]
|
||||
- text: Statistics
|
||||
- button "Settings" [ref=e289] [cursor=pointer]:
|
||||
- img [ref=e290]
|
||||
- text: Settings
|
||||
- button "Logout" [ref=e294] [cursor=pointer]:
|
||||
- img [ref=e295]
|
||||
- text: Logout
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Tasks" [level=1] [ref=e188]
|
||||
- button "Add Task" [ref=e189] [cursor=pointer]
|
||||
- generic [ref=e190]:
|
||||
- generic [ref=e191]:
|
||||
- paragraph [ref=e192]: "0"
|
||||
- paragraph [ref=e193]: Total Tasks
|
||||
- generic [ref=e194]:
|
||||
- paragraph [ref=e195]: "0"
|
||||
- paragraph [ref=e196]: Active
|
||||
- generic [ref=e197]:
|
||||
- paragraph [ref=e198]: "0"
|
||||
- paragraph [ref=e199]: Completed
|
||||
- generic [ref=e201]:
|
||||
- textbox "Search tasks..." [ref=e202]
|
||||
- combobox [ref=e203]:
|
||||
- option "All Priorities" [selected]
|
||||
- option "high"
|
||||
- option "medium"
|
||||
- option "low"
|
||||
- generic [ref=e204]:
|
||||
- button "all" [ref=e205] [cursor=pointer]
|
||||
- button "active" [ref=e206] [cursor=pointer]
|
||||
- button "completed" [ref=e207] [cursor=pointer]
|
||||
- paragraph [ref=e210]: No tasks yet. Add your first task!
|
||||
- button "AI Assistant" [ref=e211] [cursor=pointer]:
|
||||
- img [ref=e212]
|
||||
- generic [ref=e219]:
|
||||
- generic [ref=e220]:
|
||||
- generic [ref=e221]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e230]:
|
||||
- heading "AI Assistant" [level=3] [ref=e231]
|
||||
- paragraph [ref=e232]: Always here to help
|
||||
- button [ref=e234] [cursor=pointer]:
|
||||
- img [ref=e235]
|
||||
- generic [ref=e239]:
|
||||
- img [ref=e241]
|
||||
- generic [ref=e248]:
|
||||
- paragraph [ref=e249]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e250]: 04:23 PM
|
||||
- generic [ref=e251]:
|
||||
- generic [ref=e252]:
|
||||
- textbox "Type your message..." [ref=e253]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e255]:
|
||||
- button "longcat icon LongCat" [ref=e257] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e258]
|
||||
- generic [ref=e259]: LongCat
|
||||
- img [ref=e260]
|
||||
- generic [ref=e262]:
|
||||
- generic [ref=e263]: longcat
|
||||
- link "AI settings" [ref=e264] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Add New Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Add Task" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Edit Task" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- textbox "Task title *"
|
||||
- textbox "Description (optional)"
|
||||
- generic:
|
||||
- combobox:
|
||||
- option "Low Priority"
|
||||
- option "Medium Priority" [selected]
|
||||
- option "High Priority"
|
||||
- generic:
|
||||
- button "Due date (optional)":
|
||||
- generic: Due date (optional)
|
||||
- img
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Save Changes" [disabled]
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,197 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Files" [level=1] [ref=e188]
|
||||
- button "Upload File" [ref=e189] [cursor=pointer]:
|
||||
- img [ref=e190]
|
||||
- text: Upload File
|
||||
- generic [ref=e194]:
|
||||
- textbox "Search files..." [ref=e195]
|
||||
- combobox [ref=e196]:
|
||||
- option "All Tags" [selected]
|
||||
- paragraph [ref=e198]: No files uploaded yet. Upload your first file!
|
||||
- button "AI Assistant" [ref=e199] [cursor=pointer]:
|
||||
- img [ref=e200]
|
||||
- generic [ref=e207]:
|
||||
- generic [ref=e208]:
|
||||
- generic [ref=e209]:
|
||||
- img [ref=e211]
|
||||
- generic [ref=e218]:
|
||||
- heading "AI Assistant" [level=3] [ref=e219]
|
||||
- paragraph [ref=e220]: Always here to help
|
||||
- button [ref=e222] [cursor=pointer]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e227]:
|
||||
- img [ref=e229]
|
||||
- generic [ref=e236]:
|
||||
- paragraph [ref=e237]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e238]: 04:24 PM
|
||||
- generic [ref=e239]:
|
||||
- generic [ref=e240]:
|
||||
- textbox "Type your message..." [ref=e241]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e243]:
|
||||
- button "longcat icon LongCat" [ref=e245] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e246]
|
||||
- generic [ref=e247]: LongCat
|
||||
- img [ref=e248]
|
||||
- generic [ref=e250]:
|
||||
- generic [ref=e251]: longcat
|
||||
- link "AI settings" [ref=e252] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading [level=3]
|
||||
- generic: Unknown size
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic: Unknown file type
|
||||
- generic:
|
||||
- button "Download":
|
||||
- img
|
||||
- text: Download
|
||||
- button "Open":
|
||||
- img
|
||||
- text: Open
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,197 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Files" [level=1] [ref=e188]
|
||||
- button "Upload File" [ref=e189] [cursor=pointer]:
|
||||
- img [ref=e190]
|
||||
- text: Upload File
|
||||
- generic [ref=e194]:
|
||||
- textbox "Search files..." [ref=e195]
|
||||
- combobox [ref=e196]:
|
||||
- option "All Tags" [selected]
|
||||
- paragraph [ref=e198]: No files uploaded yet. Upload your first file!
|
||||
- button "AI Assistant" [ref=e199] [cursor=pointer]:
|
||||
- img [ref=e200]
|
||||
- generic [ref=e207]:
|
||||
- generic [ref=e208]:
|
||||
- generic [ref=e209]:
|
||||
- img [ref=e211]
|
||||
- generic [ref=e218]:
|
||||
- heading "AI Assistant" [level=3] [ref=e219]
|
||||
- paragraph [ref=e220]: Always here to help
|
||||
- button [ref=e222] [cursor=pointer]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e227]:
|
||||
- img [ref=e229]
|
||||
- generic [ref=e236]:
|
||||
- paragraph [ref=e237]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e238]: 04:24 PM
|
||||
- generic [ref=e239]:
|
||||
- generic [ref=e240]:
|
||||
- textbox "Type your message..." [ref=e241]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e243]:
|
||||
- button "longcat icon LongCat" [ref=e245] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e246]
|
||||
- generic [ref=e247]: LongCat
|
||||
- img [ref=e248]
|
||||
- generic [ref=e250]:
|
||||
- generic [ref=e251]: longcat
|
||||
- link "AI settings" [ref=e252] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading [level=3]
|
||||
- generic: Unknown size
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic: Unknown file type
|
||||
- generic:
|
||||
- button "Download":
|
||||
- img
|
||||
- text: Download
|
||||
- button "Open":
|
||||
- img
|
||||
- text: Open
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,197 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Files" [level=1] [ref=e188]
|
||||
- button "Upload File" [ref=e189] [cursor=pointer]:
|
||||
- img [ref=e190]
|
||||
- text: Upload File
|
||||
- generic [ref=e194]:
|
||||
- textbox "Search files..." [ref=e195]
|
||||
- combobox [ref=e196]:
|
||||
- option "All Tags" [selected]
|
||||
- paragraph [ref=e198]: No files uploaded yet. Upload your first file!
|
||||
- button "AI Assistant" [ref=e199] [cursor=pointer]:
|
||||
- img [ref=e200]
|
||||
- generic [ref=e207]:
|
||||
- generic [ref=e208]:
|
||||
- generic [ref=e209]:
|
||||
- img [ref=e211]
|
||||
- generic [ref=e218]:
|
||||
- heading "AI Assistant" [level=3] [ref=e219]
|
||||
- paragraph [ref=e220]: Always here to help
|
||||
- button [ref=e222] [cursor=pointer]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e227]:
|
||||
- img [ref=e229]
|
||||
- generic [ref=e236]:
|
||||
- paragraph [ref=e237]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e238]: 04:24 PM
|
||||
- generic [ref=e239]:
|
||||
- generic [ref=e240]:
|
||||
- textbox "Type your message..." [ref=e241]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e243]:
|
||||
- button "longcat icon LongCat" [ref=e245] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e246]
|
||||
- generic [ref=e247]: LongCat
|
||||
- img [ref=e248]
|
||||
- generic [ref=e250]:
|
||||
- generic [ref=e251]: longcat
|
||||
- link "AI settings" [ref=e252] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading [level=3]
|
||||
- generic: Unknown size
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic: Unknown file type
|
||||
- generic:
|
||||
- button "Download":
|
||||
- img
|
||||
- text: Download
|
||||
- button "Open":
|
||||
- img
|
||||
- text: Open
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,197 +0,0 @@
|
||||
- generic [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Files" [level=1] [ref=e188]
|
||||
- button "Upload File" [active] [ref=e189] [cursor=pointer]:
|
||||
- img [ref=e190]
|
||||
- text: Upload File
|
||||
- generic [ref=e194]:
|
||||
- textbox "Search files..." [ref=e195]
|
||||
- combobox [ref=e196]:
|
||||
- option "All Tags" [selected]
|
||||
- paragraph [ref=e198]: No files uploaded yet. Upload your first file!
|
||||
- button "AI Assistant" [ref=e199] [cursor=pointer]:
|
||||
- img [ref=e200]
|
||||
- generic [ref=e207]:
|
||||
- generic [ref=e208]:
|
||||
- generic [ref=e209]:
|
||||
- img [ref=e211]
|
||||
- generic [ref=e218]:
|
||||
- heading "AI Assistant" [level=3] [ref=e219]
|
||||
- paragraph [ref=e220]: Always here to help
|
||||
- button [ref=e222] [cursor=pointer]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e227]:
|
||||
- img [ref=e229]
|
||||
- generic [ref=e236]:
|
||||
- paragraph [ref=e237]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e238]: 04:24 PM
|
||||
- generic [ref=e239]:
|
||||
- generic [ref=e240]:
|
||||
- textbox "Type your message..." [ref=e241]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e243]:
|
||||
- button "longcat icon LongCat" [ref=e245] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e246]
|
||||
- generic [ref=e247]: LongCat
|
||||
- img [ref=e248]
|
||||
- generic [ref=e250]:
|
||||
- generic [ref=e251]: longcat
|
||||
- link "AI settings" [ref=e252] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading [level=3]
|
||||
- generic: Unknown size
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic: Unknown file type
|
||||
- generic:
|
||||
- button "Download":
|
||||
- img
|
||||
- text: Download
|
||||
- button "Open":
|
||||
- img
|
||||
- text: Open
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,197 +0,0 @@
|
||||
- generic [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Files" [level=1] [ref=e188]
|
||||
- button "Upload File" [active] [ref=e189] [cursor=pointer]:
|
||||
- img [ref=e190]
|
||||
- text: Upload File
|
||||
- generic [ref=e194]:
|
||||
- textbox "Search files..." [ref=e195]
|
||||
- combobox [ref=e196]:
|
||||
- option "All Tags" [selected]
|
||||
- paragraph [ref=e198]: No files uploaded yet. Upload your first file!
|
||||
- button "AI Assistant" [ref=e199] [cursor=pointer]:
|
||||
- img [ref=e200]
|
||||
- generic [ref=e207]:
|
||||
- generic [ref=e208]:
|
||||
- generic [ref=e209]:
|
||||
- img [ref=e211]
|
||||
- generic [ref=e218]:
|
||||
- heading "AI Assistant" [level=3] [ref=e219]
|
||||
- paragraph [ref=e220]: Always here to help
|
||||
- button [ref=e222] [cursor=pointer]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e227]:
|
||||
- img [ref=e229]
|
||||
- generic [ref=e236]:
|
||||
- paragraph [ref=e237]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e238]: 04:24 PM
|
||||
- generic [ref=e239]:
|
||||
- generic [ref=e240]:
|
||||
- textbox "Type your message..." [ref=e241]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e243]:
|
||||
- button "longcat icon LongCat" [ref=e245] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e246]
|
||||
- generic [ref=e247]: LongCat
|
||||
- img [ref=e248]
|
||||
- generic [ref=e250]:
|
||||
- generic [ref=e251]: longcat
|
||||
- link "AI settings" [ref=e252] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading [level=3]
|
||||
- generic: Unknown size
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic: Unknown file type
|
||||
- generic:
|
||||
- button "Download":
|
||||
- img
|
||||
- text: Download
|
||||
- button "Open":
|
||||
- img
|
||||
- text: Open
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,197 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Files" [level=1] [ref=e188]
|
||||
- button "Upload File" [ref=e189] [cursor=pointer]:
|
||||
- img [ref=e190]
|
||||
- text: Upload File
|
||||
- generic [ref=e194]:
|
||||
- textbox "Search files..." [ref=e195]
|
||||
- combobox [ref=e196]:
|
||||
- option "All Tags" [selected]
|
||||
- paragraph [ref=e198]: No files uploaded yet. Upload your first file!
|
||||
- button "AI Assistant" [ref=e199] [cursor=pointer]:
|
||||
- img [ref=e200]
|
||||
- generic [ref=e207]:
|
||||
- generic [ref=e208]:
|
||||
- generic [ref=e209]:
|
||||
- img [ref=e211]
|
||||
- generic [ref=e218]:
|
||||
- heading "AI Assistant" [level=3] [ref=e219]
|
||||
- paragraph [ref=e220]: Always here to help
|
||||
- button [ref=e222] [cursor=pointer]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e227]:
|
||||
- img [ref=e229]
|
||||
- generic [ref=e236]:
|
||||
- paragraph [ref=e237]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e238]: 04:25 PM
|
||||
- generic [ref=e239]:
|
||||
- generic [ref=e240]:
|
||||
- textbox "Type your message..." [ref=e241]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e243]:
|
||||
- button "longcat icon LongCat" [ref=e245] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e246]
|
||||
- generic [ref=e247]: LongCat
|
||||
- img [ref=e248]
|
||||
- generic [ref=e250]:
|
||||
- generic [ref=e251]: longcat
|
||||
- link "AI settings" [ref=e252] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading [level=3]
|
||||
- generic: Unknown size
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic: Unknown file type
|
||||
- generic:
|
||||
- button "Download":
|
||||
- img
|
||||
- text: Download
|
||||
- button "Open":
|
||||
- img
|
||||
- text: Open
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,197 +0,0 @@
|
||||
- generic [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Files" [level=1] [ref=e188]
|
||||
- button "Upload File" [active] [ref=e189] [cursor=pointer]:
|
||||
- img [ref=e190]
|
||||
- text: Upload File
|
||||
- generic [ref=e194]:
|
||||
- textbox "Search files..." [ref=e195]
|
||||
- combobox [ref=e196]:
|
||||
- option "All Tags" [selected]
|
||||
- paragraph [ref=e198]: No files uploaded yet. Upload your first file!
|
||||
- button "AI Assistant" [ref=e199] [cursor=pointer]:
|
||||
- img [ref=e200]
|
||||
- generic [ref=e207]:
|
||||
- generic [ref=e208]:
|
||||
- generic [ref=e209]:
|
||||
- img [ref=e211]
|
||||
- generic [ref=e218]:
|
||||
- heading "AI Assistant" [level=3] [ref=e219]
|
||||
- paragraph [ref=e220]: Always here to help
|
||||
- button [ref=e222] [cursor=pointer]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e227]:
|
||||
- img [ref=e229]
|
||||
- generic [ref=e236]:
|
||||
- paragraph [ref=e237]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e238]: 04:25 PM
|
||||
- generic [ref=e239]:
|
||||
- generic [ref=e240]:
|
||||
- textbox "Type your message..." [ref=e241]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e243]:
|
||||
- button "longcat icon LongCat" [ref=e245] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e246]
|
||||
- generic [ref=e247]: LongCat
|
||||
- img [ref=e248]
|
||||
- generic [ref=e250]:
|
||||
- generic [ref=e251]: longcat
|
||||
- link "AI settings" [ref=e252] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading [level=3]
|
||||
- generic: Unknown size
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic: Unknown file type
|
||||
- generic:
|
||||
- button "Download":
|
||||
- img
|
||||
- text: Download
|
||||
- button "Open":
|
||||
- img
|
||||
- text: Open
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,197 +0,0 @@
|
||||
- generic [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Files" [level=1] [ref=e188]
|
||||
- button "Upload File" [active] [ref=e189] [cursor=pointer]:
|
||||
- img [ref=e190]
|
||||
- text: Upload File
|
||||
- generic [ref=e194]:
|
||||
- textbox "Search files..." [ref=e195]
|
||||
- combobox [ref=e196]:
|
||||
- option "All Tags" [selected]
|
||||
- paragraph [ref=e198]: No files uploaded yet. Upload your first file!
|
||||
- button "AI Assistant" [ref=e199] [cursor=pointer]:
|
||||
- img [ref=e200]
|
||||
- generic [ref=e207]:
|
||||
- generic [ref=e208]:
|
||||
- generic [ref=e209]:
|
||||
- img [ref=e211]
|
||||
- generic [ref=e218]:
|
||||
- heading "AI Assistant" [level=3] [ref=e219]
|
||||
- paragraph [ref=e220]: Always here to help
|
||||
- button [ref=e222] [cursor=pointer]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e227]:
|
||||
- img [ref=e229]
|
||||
- generic [ref=e236]:
|
||||
- paragraph [ref=e237]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e238]: 04:25 PM
|
||||
- generic [ref=e239]:
|
||||
- generic [ref=e240]:
|
||||
- textbox "Type your message..." [ref=e241]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e243]:
|
||||
- button "longcat icon LongCat" [ref=e245] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e246]
|
||||
- generic [ref=e247]: LongCat
|
||||
- img [ref=e248]
|
||||
- generic [ref=e250]:
|
||||
- generic [ref=e251]: longcat
|
||||
- link "AI settings" [ref=e252] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading [level=3]
|
||||
- generic: Unknown size
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic: Unknown file type
|
||||
- generic:
|
||||
- button "Download":
|
||||
- img
|
||||
- text: Download
|
||||
- button "Open":
|
||||
- img
|
||||
- text: Open
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,14 +0,0 @@
|
||||
- generic [ref=e5]:
|
||||
- generic [ref=e7]:
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- heading "Authentication Required" [level=1] [ref=e11]
|
||||
- paragraph [ref=e12]: Please sign in to access Trackeep
|
||||
- generic [ref=e13]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e19]:
|
||||
- heading "Authentication Required" [level=3] [ref=e20]
|
||||
- paragraph [ref=e21]: You need to be authenticated to access this page. Please sign in or create an account to continue.
|
||||
- generic [ref=e22]:
|
||||
- button "Sign In" [ref=e23] [cursor=pointer]
|
||||
- button "Create Account" [ref=e24] [cursor=pointer]
|
||||
@@ -1,197 +0,0 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Files" [level=1] [ref=e188]
|
||||
- button "Upload File" [ref=e189] [cursor=pointer]:
|
||||
- img [ref=e190]
|
||||
- text: Upload File
|
||||
- generic [ref=e194]:
|
||||
- textbox "Search files..." [ref=e195]
|
||||
- combobox [ref=e196]:
|
||||
- option "All Tags" [selected]
|
||||
- paragraph [ref=e198]: No files uploaded yet. Upload your first file!
|
||||
- button "AI Assistant" [ref=e199] [cursor=pointer]:
|
||||
- img [ref=e200]
|
||||
- generic [ref=e207]:
|
||||
- generic [ref=e208]:
|
||||
- generic [ref=e209]:
|
||||
- img [ref=e211]
|
||||
- generic [ref=e218]:
|
||||
- heading "AI Assistant" [level=3] [ref=e219]
|
||||
- paragraph [ref=e220]: Always here to help
|
||||
- button [ref=e222] [cursor=pointer]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e227]:
|
||||
- img [ref=e229]
|
||||
- generic [ref=e236]:
|
||||
- paragraph [ref=e237]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e238]: 04:26 PM
|
||||
- generic [ref=e239]:
|
||||
- generic [ref=e240]:
|
||||
- textbox "Type your message..." [ref=e241]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e243]:
|
||||
- button "longcat icon LongCat" [ref=e245] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e246]
|
||||
- generic [ref=e247]: LongCat
|
||||
- img [ref=e248]
|
||||
- generic [ref=e250]:
|
||||
- generic [ref=e251]: longcat
|
||||
- link "AI settings" [ref=e252] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading [level=3]
|
||||
- generic: Unknown size
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic: Unknown file type
|
||||
- generic:
|
||||
- button "Download":
|
||||
- img
|
||||
- text: Download
|
||||
- button "Open":
|
||||
- img
|
||||
- text: Open
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -1,197 +0,0 @@
|
||||
- generic [ref=e1]:
|
||||
- generic [ref=e4]:
|
||||
- generic [ref=e7]:
|
||||
- link "Trackeep Logo Trackeep" [ref=e9] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- img "Trackeep Logo" [ref=e10]
|
||||
- generic [ref=e11]: Trackeep
|
||||
- group [ref=e13]:
|
||||
- button "Trackeep Workspace" [ref=e14] [cursor=pointer]:
|
||||
- generic [ref=e15]:
|
||||
- img [ref=e17]
|
||||
- generic [ref=e20]: Trackeep Workspace
|
||||
- img [ref=e22]
|
||||
- navigation [ref=e24]:
|
||||
- link "Home" [ref=e25] [cursor=pointer]:
|
||||
- /url: /app
|
||||
- generic [ref=e26]:
|
||||
- img [ref=e27]
|
||||
- generic [ref=e31]: Home
|
||||
- link "Bookmarks" [ref=e33] [cursor=pointer]:
|
||||
- /url: /app/bookmarks
|
||||
- generic [ref=e34]:
|
||||
- img [ref=e35]
|
||||
- generic [ref=e37]: Bookmarks
|
||||
- link "Tasks" [ref=e39] [cursor=pointer]:
|
||||
- /url: /app/tasks
|
||||
- generic [ref=e40]:
|
||||
- img [ref=e41]
|
||||
- generic [ref=e44]: Tasks
|
||||
- link "Time Tracking" [ref=e46] [cursor=pointer]:
|
||||
- /url: /app/time-tracking
|
||||
- generic [ref=e47]:
|
||||
- img [ref=e48]
|
||||
- generic [ref=e51]: Time Tracking
|
||||
- link "Calendar" [ref=e53] [cursor=pointer]:
|
||||
- /url: /app/calendar
|
||||
- generic [ref=e54]:
|
||||
- img [ref=e55]
|
||||
- generic [ref=e57]: Calendar
|
||||
- link "Files" [ref=e59] [cursor=pointer]:
|
||||
- /url: /app/files
|
||||
- generic [ref=e60]:
|
||||
- img [ref=e61]
|
||||
- generic [ref=e63]: Files
|
||||
- link "Notes" [ref=e65] [cursor=pointer]:
|
||||
- /url: /app/notes
|
||||
- generic [ref=e66]:
|
||||
- img [ref=e67]
|
||||
- generic [ref=e69]: Notes
|
||||
- link "Messages" [ref=e71] [cursor=pointer]:
|
||||
- /url: /app/messages
|
||||
- generic [ref=e72]:
|
||||
- img [ref=e73]
|
||||
- generic [ref=e75]: Messages
|
||||
- link "YouTube" [ref=e77] [cursor=pointer]:
|
||||
- /url: /app/youtube
|
||||
- generic [ref=e78]:
|
||||
- img [ref=e79]
|
||||
- generic [ref=e82]: YouTube
|
||||
- link "Members" [ref=e84] [cursor=pointer]:
|
||||
- /url: /app/members
|
||||
- generic [ref=e85]:
|
||||
- img [ref=e86]
|
||||
- generic [ref=e91]: Members
|
||||
- link "Learning" [ref=e93] [cursor=pointer]:
|
||||
- /url: /app/learning-paths
|
||||
- generic [ref=e94]:
|
||||
- img [ref=e95]
|
||||
- generic [ref=e98]: Learning
|
||||
- link "Stats" [ref=e100] [cursor=pointer]:
|
||||
- /url: /app/stats
|
||||
- generic [ref=e101]:
|
||||
- img [ref=e102]
|
||||
- generic [ref=e104]: Stats
|
||||
- link "GitHub" [ref=e106] [cursor=pointer]:
|
||||
- /url: /app/github
|
||||
- generic [ref=e107]:
|
||||
- img [ref=e108]
|
||||
- generic [ref=e110]: GitHub
|
||||
- link "AI Assistant" [ref=e112] [cursor=pointer]:
|
||||
- /url: /app/chat
|
||||
- generic [ref=e113]:
|
||||
- img [ref=e114]
|
||||
- generic [ref=e121]: AI Assistant
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e125]: Version 1.0.0
|
||||
- button "Update Failed" [ref=e126] [cursor=pointer]:
|
||||
- generic [ref=e127]:
|
||||
- img [ref=e128]
|
||||
- generic [ref=e130]: Update Failed
|
||||
- navigation [ref=e132]:
|
||||
- link "Removed stuff" [ref=e133] [cursor=pointer]:
|
||||
- /url: /app/removed-stuff
|
||||
- generic [ref=e134]:
|
||||
- img [ref=e135]
|
||||
- generic [ref=e138]: Removed stuff
|
||||
- link "Settings" [ref=e140] [cursor=pointer]:
|
||||
- /url: /app/settings
|
||||
- generic [ref=e141]:
|
||||
- img [ref=e142]
|
||||
- generic [ref=e145]: Settings
|
||||
- button "Logout" [ref=e147] [cursor=pointer]:
|
||||
- generic [ref=e148]:
|
||||
- img [ref=e149]
|
||||
- generic [ref=e153]: Logout
|
||||
- generic [ref=e155]:
|
||||
- generic [ref=e156]:
|
||||
- generic [ref=e157]:
|
||||
- button [ref=e158] [cursor=pointer]:
|
||||
- img [ref=e159]
|
||||
- button "Quick search" [ref=e160] [cursor=pointer]:
|
||||
- img [ref=e161]
|
||||
- text: Quick search
|
||||
- generic [ref=e164]:
|
||||
- button "Import a document" [ref=e165] [cursor=pointer]:
|
||||
- img [ref=e166]
|
||||
- text: Import a document
|
||||
- button [ref=e170] [cursor=pointer]:
|
||||
- img [ref=e171]
|
||||
- img [ref=e176]
|
||||
- button "AU" [ref=e180] [cursor=pointer]:
|
||||
- generic [ref=e181]: AU
|
||||
- img [ref=e182]
|
||||
- main [ref=e184]:
|
||||
- generic [ref=e186]:
|
||||
- generic [ref=e187]:
|
||||
- heading "Files" [level=1] [ref=e188]
|
||||
- button "Upload File" [active] [ref=e189] [cursor=pointer]:
|
||||
- img [ref=e190]
|
||||
- text: Upload File
|
||||
- generic [ref=e194]:
|
||||
- textbox "Search files..." [ref=e195]
|
||||
- combobox [ref=e196]:
|
||||
- option "All Tags" [selected]
|
||||
- paragraph [ref=e198]: No files uploaded yet. Upload your first file!
|
||||
- button "AI Assistant" [ref=e199] [cursor=pointer]:
|
||||
- img [ref=e200]
|
||||
- generic [ref=e207]:
|
||||
- generic [ref=e208]:
|
||||
- generic [ref=e209]:
|
||||
- img [ref=e211]
|
||||
- generic [ref=e218]:
|
||||
- heading "AI Assistant" [level=3] [ref=e219]
|
||||
- paragraph [ref=e220]: Always here to help
|
||||
- button [ref=e222] [cursor=pointer]:
|
||||
- img [ref=e223]
|
||||
- generic [ref=e227]:
|
||||
- img [ref=e229]
|
||||
- generic [ref=e236]:
|
||||
- paragraph [ref=e237]: Hello! I'm your AI assistant. How can I help you today?
|
||||
- paragraph [ref=e238]: 04:26 PM
|
||||
- generic [ref=e239]:
|
||||
- generic [ref=e240]:
|
||||
- textbox "Type your message..." [ref=e241]
|
||||
- button [disabled]:
|
||||
- img
|
||||
- generic [ref=e243]:
|
||||
- button "longcat icon LongCat" [ref=e245] [cursor=pointer]:
|
||||
- img "longcat icon" [ref=e246]
|
||||
- generic [ref=e247]: LongCat
|
||||
- img [ref=e248]
|
||||
- generic [ref=e250]:
|
||||
- generic [ref=e251]: longcat
|
||||
- link "AI settings" [ref=e252] [cursor=pointer]:
|
||||
- /url: /app/settings#ai
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading [level=3]
|
||||
- generic: Unknown size
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic: Unknown file type
|
||||
- generic:
|
||||
- button "Download":
|
||||
- img
|
||||
- text: Download
|
||||
- button "Open":
|
||||
- img
|
||||
- text: Open
|
||||
- generic:
|
||||
- generic:
|
||||
- generic:
|
||||
- heading "Import Documents" [level=3]
|
||||
- button:
|
||||
- img
|
||||
- generic:
|
||||
- generic:
|
||||
- img
|
||||
- heading "Drop files here" [level=4]
|
||||
- paragraph: or click to browse
|
||||
- button "Browse Files"
|
||||
- generic:
|
||||
- button "Cancel"
|
||||
- button "Upload 0 Files" [disabled]
|
||||
@@ -0,0 +1,134 @@
|
||||
# Changelog
|
||||
|
||||
## [1.3.0] - Production Ready Release - 2026-04-06
|
||||
|
||||
### Added
|
||||
- **Production Deployment Guide**: Comprehensive documentation for deploying to production
|
||||
- **Error Handler Middleware**: Centralized error handling with panic recovery
|
||||
- **Graceful Shutdown**: Proper cleanup of resources on server shutdown
|
||||
- **Production Configuration**: Optimized settings for production environments
|
||||
- **Health Check Endpoints**: `/health`, `/ready`, and `/live` for monitoring
|
||||
- **Database Connection Pooling**: Configured for optimal performance
|
||||
- **Rate Limiting**: Protection against abuse and DDoS
|
||||
- **Audit Logging**: Complete tracking of all user actions
|
||||
- **Security Headers**: HSTS, CSP, X-Frame-Options, etc.
|
||||
- **Docker Production Compose**: Optimized docker-compose.prod.yml with resource limits
|
||||
- **Automated Testing Script**: Pre-deployment validation script
|
||||
- **Backup Scripts**: Automated database and file backups
|
||||
- **Monitoring Setup**: Prometheus and Grafana integration ready
|
||||
|
||||
### Fixed
|
||||
- **Debug Logging**: Removed all `fmt.Printf` debug statements from production code
|
||||
- **Graceful Exit**: Changed `os.Exit(0)` to proper graceful shutdown in update handler
|
||||
- **Error Handling**: Improved error responses across all handlers
|
||||
- **Search Handler**: Removed verbose debug logging from Brave Search API calls
|
||||
- **Semantic Search**: Replaced fmt.Printf with proper log.Printf calls
|
||||
- **Web Scraping**: Added proper logging instead of fmt.Printf
|
||||
- **Border Consistency**: Fixed dark mode border colors (#262626) across all components
|
||||
- **Scrollbar Styling**: Consistent scrollbar appearance in light and dark modes
|
||||
- **Input Validation**: Enhanced security with better input sanitization
|
||||
- **CORS Configuration**: Proper CORS setup for production environments
|
||||
|
||||
### Improved
|
||||
- **Database Migrations**: Auto-migration with fallback to legacy SQL migrations
|
||||
- **Cache Strategy**: DragonflyDB integration with intelligent caching
|
||||
- **Session Management**: Redis-backed sessions with automatic cleanup
|
||||
- **Performance**: Optimized database queries and connection pooling
|
||||
- **Security**: Enhanced JWT validation and encryption
|
||||
- **Logging**: Structured logging with proper log levels
|
||||
- **Documentation**: Comprehensive deployment and maintenance guides
|
||||
- **Frontend Styling**: Consistent Papra design system implementation
|
||||
- **Dark Mode**: Perfect #262626 border consistency
|
||||
- **Light Mode**: Enhanced shadows and better contrast
|
||||
- **Responsive Design**: Improved mobile and tablet layouts
|
||||
|
||||
### Security
|
||||
- **Input Validation**: Comprehensive validation middleware
|
||||
- **SQL Injection Protection**: Parameterized queries throughout
|
||||
- **XSS Protection**: Proper output encoding
|
||||
- **CSRF Protection**: Token-based CSRF prevention
|
||||
- **Rate Limiting**: Per-endpoint rate limiting
|
||||
- **Secure Cookies**: HTTPOnly and Secure flags
|
||||
- **Password Hashing**: Bcrypt with proper cost factor
|
||||
- **2FA Support**: TOTP-based two-factor authentication
|
||||
- **API Key Management**: Secure API key generation and validation
|
||||
- **Audit Trail**: Complete audit logging of security events
|
||||
|
||||
### Performance
|
||||
- **Database Indexing**: Optimized indexes on frequently queried fields
|
||||
- **Query Optimization**: Reduced N+1 queries
|
||||
- **Caching Layer**: DragonflyDB for session and data caching
|
||||
- **Connection Pooling**: Configured for high concurrency
|
||||
- **Gzip Compression**: Enabled for API responses
|
||||
- **Static Asset Caching**: Browser caching headers
|
||||
- **Lazy Loading**: Frontend components load on demand
|
||||
- **Code Splitting**: Optimized bundle sizes
|
||||
|
||||
### DevOps
|
||||
- **Docker Multi-Stage Builds**: Smaller image sizes
|
||||
- **Health Checks**: Kubernetes-ready health endpoints
|
||||
- **Log Rotation**: Automatic log management
|
||||
- **Resource Limits**: CPU and memory limits in Docker
|
||||
- **Horizontal Scaling**: Load balancer ready
|
||||
- **Zero-Downtime Deploys**: Rolling update support
|
||||
- **Backup Automation**: Scheduled backups with retention
|
||||
- **Monitoring**: Metrics and alerting ready
|
||||
|
||||
### Breaking Changes
|
||||
- None - fully backward compatible
|
||||
|
||||
### Deprecated
|
||||
- Legacy UUID-based schema (auto-migrates to new schema)
|
||||
- In-memory sessions (replaced with Redis-backed sessions)
|
||||
|
||||
### Migration Notes
|
||||
- Run `go mod tidy` in backend directory
|
||||
- Update `.env` file with production values
|
||||
- Generate new JWT_SECRET and ENCRYPTION_KEY
|
||||
- Review and update CORS settings
|
||||
- Configure SSL certificates for HTTPS
|
||||
- Set up database backups
|
||||
- Configure monitoring and alerting
|
||||
|
||||
### Known Issues
|
||||
- Computer vision OCR is placeholder implementation (requires Tesseract integration)
|
||||
- GeoIP detection returns "unknown" (requires GeoIP database)
|
||||
- Email sending requires SMTP configuration
|
||||
- Screenshot capture requires Chrome/Chromium installation
|
||||
|
||||
### Upgrade Instructions
|
||||
1. Backup your database: `./backup-trackeep.sh`
|
||||
2. Pull latest changes: `git pull origin main`
|
||||
3. Update dependencies: `cd backend && go mod tidy && cd ../frontend && npm install`
|
||||
4. Rebuild containers: `docker-compose -f docker-compose.prod.yml build`
|
||||
5. Run migrations: `docker-compose -f docker-compose.prod.yml up -d`
|
||||
6. Verify health: `curl http://localhost:8080/health`
|
||||
|
||||
### Contributors
|
||||
- Enhanced by AI Assistant (Kiro)
|
||||
- Original project by Dvorinka
|
||||
|
||||
### Support
|
||||
- GitHub Issues: https://github.com/Dvorinka/Trackeep/issues
|
||||
- Documentation: See PRODUCTION_DEPLOYMENT.md
|
||||
|
||||
---
|
||||
|
||||
## [1.2.5] - Previous Release
|
||||
|
||||
### Features
|
||||
- Full-stack learning and productivity platform
|
||||
- User authentication with JWT
|
||||
- Bookmark management with metadata
|
||||
- Task tracking with priorities
|
||||
- File upload and sharing
|
||||
- Notes with encryption
|
||||
- Chat with AI integration
|
||||
- YouTube video bookmarks
|
||||
- GitHub integration
|
||||
- Time tracking
|
||||
- Calendar events
|
||||
- Analytics dashboard
|
||||
- Learning paths
|
||||
- And much more...
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
# Trackeep Deployment Guide
|
||||
|
||||
## Flexible Deployment Options
|
||||
|
||||
Trackeep is designed to work in various deployment scenarios:
|
||||
|
||||
### 1. Local Development (localhost)
|
||||
```bash
|
||||
# Start with default settings
|
||||
docker compose up -d
|
||||
|
||||
# Frontend will be available via nginx on port 80
|
||||
# Backend API on port 8080
|
||||
# Frontend automatically detects API URL: http://localhost:8080/api/v1
|
||||
```
|
||||
|
||||
### 2. Home Network Deployment
|
||||
```bash
|
||||
# Set your HOST environment variable
|
||||
export HOST=192.168.1.100:8080
|
||||
|
||||
# Or modify .env
|
||||
echo "HOST=192.168.1.100:8080" >> .env
|
||||
|
||||
docker compose up -d
|
||||
|
||||
# Access from any device on your network
|
||||
# Frontend: http://192.168.1.100
|
||||
# API: http://192.168.1.100:8080/api/v1
|
||||
```
|
||||
|
||||
### 3. Domain with Cloudflare/Reverse Proxy
|
||||
```bash
|
||||
# Set HOST to your domain
|
||||
export HOST=yourdomain.com
|
||||
|
||||
# Configure CORS for your domain
|
||||
export CORS_ALLOWED_ORIGINS=https://yourdomain.com
|
||||
|
||||
docker compose up -d
|
||||
|
||||
# Configure Cloudflare to proxy:
|
||||
# - yourdomain.com → backend:8080
|
||||
# - app.yourdomain.com → frontend:80
|
||||
```
|
||||
|
||||
### 4. Production HTTPS
|
||||
```bash
|
||||
# Set production mode
|
||||
export GIN_MODE=release
|
||||
export HOST=yourdomain.com
|
||||
export CORS_ALLOWED_ORIGINS=https://yourdomain.com
|
||||
|
||||
# Use SSL certificates (via Traefik, Nginx, etc.)
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
### Core Configuration
|
||||
- `PORT=8080` - Backend port only
|
||||
- `GIN_MODE=debug|release` - Application mode
|
||||
- `HOST=` - Auto-detection fallback (optional)
|
||||
- `CORS_ALLOWED_ORIGINS=*` - Flexible CORS (restrict in production)
|
||||
|
||||
### Removed Variables
|
||||
- ❌ `FRONTEND_PORT` - No longer needed
|
||||
- ❌ `OAUTH_PORT` - Moved to oauth-service/.env
|
||||
- ❌ `VITE_API_URL` - Auto-detected via /api/v1/config
|
||||
|
||||
### OAuth Service (Separate)
|
||||
See `oauth-service/.env.example` for OAuth-specific configuration.
|
||||
|
||||
## API Detection
|
||||
|
||||
The frontend automatically detects the API URL by:
|
||||
1. Calling `/api/v1/config` endpoint
|
||||
2. Using the current request's scheme and host
|
||||
3. Falling back to `HOST` environment variable
|
||||
4. Final fallback to `localhost:8080`
|
||||
|
||||
## Port Management
|
||||
|
||||
- **Backend**: Fixed port 8080 (required for API)
|
||||
- **Frontend**: No port mapping (uses nginx:80 internally)
|
||||
- **OAuth**: Separate service on port 9090
|
||||
- **Database**: Port 5432 (internal to Docker network)
|
||||
|
||||
This flexibility allows Trackeep to adapt to any deployment scenario while maintaining a consistent configuration approach.
|
||||
@@ -0,0 +1,55 @@
|
||||
# Multi-stage build for unified Trackeep image
|
||||
# Builds both frontend and backend in one package
|
||||
|
||||
# Stage 1: Build Frontend
|
||||
FROM node:22-alpine AS frontend-builder
|
||||
WORKDIR /app/frontend
|
||||
COPY frontend/package*.json ./
|
||||
RUN npm install
|
||||
COPY frontend/ ./
|
||||
RUN npm run build
|
||||
|
||||
# Stage 2: Build Backend
|
||||
FROM golang:1.25-alpine AS backend-builder
|
||||
WORKDIR /app/backend
|
||||
COPY backend/go.mod backend/go.sum ./
|
||||
RUN go mod download
|
||||
COPY backend/ ./
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
|
||||
|
||||
# Stage 3: Final unified image
|
||||
FROM alpine:latest
|
||||
|
||||
# Install dependencies
|
||||
RUN apk --no-cache add ca-certificates tzdata nginx
|
||||
|
||||
# Copy backend binary and migrations
|
||||
COPY --from=backend-builder /app/backend/main /app/main
|
||||
COPY --from=backend-builder /app/backend/migrations /app/migrations
|
||||
|
||||
# Copy frontend build
|
||||
COPY --from=frontend-builder /app/frontend/dist /usr/share/nginx/html
|
||||
|
||||
# Copy branding assets
|
||||
COPY trackeep.svg /usr/share/nginx/html/
|
||||
COPY trackeepfavi.png /usr/share/nginx/html/
|
||||
COPY trackeepfavi_bg.png /usr/share/nginx/html/
|
||||
|
||||
# Copy nginx configuration
|
||||
COPY frontend/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
# Create directories
|
||||
RUN mkdir -p /app/uploads /data /var/log/nginx
|
||||
|
||||
# Expose single port
|
||||
EXPOSE 8080
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
|
||||
|
||||
# Start script to run both backend and nginx
|
||||
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
||||
RUN chmod +x /docker-entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
@@ -1,33 +0,0 @@
|
||||
/* global chrome */
|
||||
|
||||
// Create context menu when extension is installed
|
||||
chrome.runtime.onInstalled.addListener(() => {
|
||||
chrome.contextMenus.create({
|
||||
id: 'save-to-trackeep',
|
||||
title: 'Save to Trackeep',
|
||||
contexts: ['page', 'link', 'selection', 'image', 'video']
|
||||
});
|
||||
});
|
||||
|
||||
// Handle context menu click
|
||||
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
|
||||
if (info.menuItemId !== 'save-to-trackeep') return;
|
||||
|
||||
// Open popup with pre-filled data based on context
|
||||
const url = info.linkUrl || info.srcUrl || tab?.url || '';
|
||||
const title = tab?.title || '';
|
||||
const selection = info.selectionText || '';
|
||||
|
||||
// Store temporary data for popup to read
|
||||
chrome.storage.local.set({
|
||||
contextMenuData: {
|
||||
url,
|
||||
title,
|
||||
selection,
|
||||
timestamp: Date.now()
|
||||
}
|
||||
}, () => {
|
||||
// Open the popup (or focus it if already open)
|
||||
chrome.action.openPopup();
|
||||
});
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Trackeep Saver",
|
||||
"version": "0.1.0",
|
||||
"description": "Save the current page or a file to your Trackeep account as a bookmark or upload.",
|
||||
"action": {
|
||||
"default_popup": "popup.html",
|
||||
"default_title": "Save to Trackeep"
|
||||
},
|
||||
"options_page": "options.html",
|
||||
"background": {
|
||||
"service_worker": "background.js"
|
||||
},
|
||||
"permissions": [
|
||||
"storage",
|
||||
"tabs",
|
||||
"activeTab",
|
||||
"contextMenus"
|
||||
],
|
||||
"host_permissions": [
|
||||
"<all_urls>"
|
||||
],
|
||||
"icons": {
|
||||
"16": "icons/icon16.png",
|
||||
"32": "icons/icon32.png",
|
||||
"48": "icons/icon48.png",
|
||||
"128": "icons/icon128.png"
|
||||
}
|
||||
}
|
||||
@@ -1,531 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-kb-theme="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Trackeep Saver – Options</title>
|
||||
<style>
|
||||
/* Modern Inter Font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
||||
|
||||
/* Modern CSS Variables - Proton Pass Inspired */
|
||||
:root {
|
||||
--bg-primary: #0f0f0f;
|
||||
--bg-secondary: #1a1a1a;
|
||||
--bg-tertiary: #262626;
|
||||
--bg-hover: #2a2a2a;
|
||||
--bg-active: #333333;
|
||||
--border-primary: #2a2a2a;
|
||||
--border-secondary: #333333;
|
||||
--text-primary: #ffffff;
|
||||
--text-secondary: #a3a3a3;
|
||||
--text-tertiary: #737373;
|
||||
--accent-primary: #3b82f6;
|
||||
--accent-hover: #2563eb;
|
||||
--success: #10b981;
|
||||
--warning: #f59e0b;
|
||||
--error: #ef4444;
|
||||
--gradient-primary: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
--gradient-secondary: linear-gradient(135deg, #1a1a1a 0%, #262626 100%);
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5);
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 8px;
|
||||
--radius-lg: 12px;
|
||||
--radius-xl: 16px;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
line-height: 1.6;
|
||||
font-size: 14px;
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.header {
|
||||
background: var(--gradient-secondary);
|
||||
padding: 32px 20px 20px;
|
||||
border-bottom: 1px solid var(--border-primary);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.header::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 3px;
|
||||
background: var(--gradient-primary);
|
||||
}
|
||||
|
||||
.header-content {
|
||||
max-width: 640px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--gradient-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
box-shadow: var(--shadow-lg);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.logo::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: linear-gradient(45deg, transparent, rgba(255,255,255,0.1), transparent);
|
||||
transform: rotate(45deg);
|
||||
animation: shimmer 3s infinite;
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); }
|
||||
100% { transform: translateX(100%) translateY(100%) rotate(45deg); }
|
||||
}
|
||||
|
||||
.title-section {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin: 0 0 4px 0;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Main Content */
|
||||
.container {
|
||||
max-width: 640px;
|
||||
margin: 0 auto;
|
||||
padding: 32px 20px;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.section {
|
||||
background: var(--bg-secondary);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 24px;
|
||||
border: 1px solid var(--border-primary);
|
||||
margin-bottom: 24px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.section:hover {
|
||||
border-color: var(--border-secondary);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.section-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--gradient-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Form Elements */
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.form-group:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 8px;
|
||||
color: var(--text-secondary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="url"],
|
||||
input[type="password"] {
|
||||
width: 100%;
|
||||
padding: 14px 16px;
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid var(--border-primary);
|
||||
background: var(--bg-tertiary);
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 400;
|
||||
transition: all 0.2s ease;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="url"]:focus,
|
||||
input[type="password"]:focus {
|
||||
border-color: var(--accent-primary);
|
||||
background: var(--bg-hover);
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
|
||||
/* Instructions */
|
||||
.instructions {
|
||||
background: var(--bg-tertiary);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 16px;
|
||||
border: 1px solid var(--border-primary);
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.instructions-title {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0 0 8px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.instructions-list {
|
||||
font-size: 13px;
|
||||
color: var(--text-secondary);
|
||||
margin: 0;
|
||||
padding-left: 16px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.instructions-list li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.instructions-list li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
padding: 14px 24px;
|
||||
border-radius: var(--radius-md);
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
font-family: 'Inter', sans-serif;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
outline: none;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.btn:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--gradient-primary);
|
||||
color: white;
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.btn-primary:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
/* Status Messages */
|
||||
.status-message {
|
||||
padding: 16px 20px;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
animation: slideUp 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.status-message.success {
|
||||
background: rgba(16, 185, 129, 0.1);
|
||||
color: var(--success);
|
||||
border: 1px solid rgba(16, 185, 129, 0.2);
|
||||
}
|
||||
|
||||
.status-message.error {
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
color: var(--error);
|
||||
border: 1px solid rgba(239, 68, 68, 0.2);
|
||||
}
|
||||
|
||||
.status-message.info {
|
||||
background: rgba(59, 130, 246, 0.1);
|
||||
color: var(--accent-primary);
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
|
||||
/* Code styling */
|
||||
code {
|
||||
background: var(--bg-tertiary);
|
||||
padding: 3px 8px;
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 12px;
|
||||
color: var(--text-primary);
|
||||
border: 1px solid var(--border-primary);
|
||||
font-family: 'Fira Code', 'Monaco', 'Consolas', monospace;
|
||||
}
|
||||
|
||||
/* Icon System */
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.icon-sm {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.icon-lg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.icon-xl {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
/* Icon animations */
|
||||
.icon-spin {
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
.icon-pulse {
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; transform: scale(1); }
|
||||
50% { opacity: 0.8; transform: scale(1.05); }
|
||||
}
|
||||
|
||||
/* Enhanced button icons */
|
||||
.btn .icon {
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.btn:hover .icon {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.btn:active .icon {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* Section icon enhancements */
|
||||
.section-icon {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.section:hover .section-icon {
|
||||
transform: scale(1.05) rotate(5deg);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 640px) {
|
||||
.container {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 24px 16px 16px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header -->
|
||||
<header class="header">
|
||||
<div class="header-content">
|
||||
<div class="logo-container">
|
||||
<div class="logo">T</div>
|
||||
<div class="title-section">
|
||||
<h1 class="title">Trackeep Saver</h1>
|
||||
<p class="subtitle">Configure your extension settings</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="container">
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="section-icon">
|
||||
<svg class="icon-xl" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
<path d="M12 1v6m0 6v6m4.22-13.22l4.24 4.24M1.54 1.54l4.24 4.24M1 12h6m6 0h6"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="section-title">API Configuration</h2>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="apiBaseUrl">Trackeep API Base URL</label>
|
||||
<input
|
||||
id="apiBaseUrl"
|
||||
type="url"
|
||||
placeholder="https://your-domain.example.com/api/v1 or http://localhost:8080/api/v1"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="authToken">Authentication Token (JWT)</label>
|
||||
<input
|
||||
id="authToken"
|
||||
type="password"
|
||||
placeholder="Paste your Trackeep authentication token here"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="instructions">
|
||||
<div class="instructions-title">
|
||||
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
||||
<polyline points="14,2 14,8 20,8"/>
|
||||
<line x1="16" y1="13" x2="8" y2="13"/>
|
||||
<line x1="16" y1="17" x2="8" y2="17"/>
|
||||
<polyline points="10,9 9,9 8,9"/>
|
||||
</svg>
|
||||
<span>How to get your authentication token:</span>
|
||||
</div>
|
||||
<ol class="instructions-list">
|
||||
<li>Log into your Trackeep account in your browser</li>
|
||||
<li>Open Developer Tools (F12) → Application → Local Storage</li>
|
||||
<li>Find key <code>trackeep_token</code> and copy its value</li>
|
||||
<li>Paste token in field above</li>
|
||||
<li><strong>Never share this token publicly</strong> - it provides full access to your account</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary" id="saveBtn" style="margin-top: 24px;">
|
||||
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
|
||||
<polyline points="17,21 17,13 7,13 7,21"/>
|
||||
<polyline points="7,3 7,8 15,8"/>
|
||||
</svg>
|
||||
<span>Save Settings</span>
|
||||
</button>
|
||||
|
||||
<div id="statusMessage" class="status-message" style="display: none;"></div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script src="options.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,136 +0,0 @@
|
||||
/* global chrome */
|
||||
|
||||
const apiBaseUrlInput = document.getElementById('apiBaseUrl');
|
||||
const authTokenInput = document.getElementById('authToken');
|
||||
const saveBtn = document.getElementById('saveBtn');
|
||||
const statusMessageEl = document.getElementById('statusMessage');
|
||||
|
||||
function showMessage(message, type = 'info', duration = 5000) {
|
||||
statusMessageEl.textContent = message;
|
||||
statusMessageEl.className = `status-message ${type}`;
|
||||
statusMessageEl.style.display = 'flex';
|
||||
|
||||
if (duration > 0) {
|
||||
setTimeout(() => {
|
||||
statusMessageEl.style.display = 'none';
|
||||
}, duration);
|
||||
}
|
||||
}
|
||||
|
||||
function hideMessage() {
|
||||
statusMessageEl.style.display = 'none';
|
||||
}
|
||||
|
||||
function setButtonLoading(button, loading = true) {
|
||||
if (loading) {
|
||||
button.disabled = true;
|
||||
const originalContent = button.innerHTML;
|
||||
button.dataset.originalContent = originalContent;
|
||||
button.innerHTML = `
|
||||
<svg class="icon icon-spin" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M21 12a9 9 0 1 1-6.219-8.56"/>
|
||||
</svg>
|
||||
<span>Saving...</span>
|
||||
`;
|
||||
} else {
|
||||
button.disabled = false;
|
||||
if (button.dataset.originalContent) {
|
||||
button.innerHTML = button.dataset.originalContent;
|
||||
delete button.dataset.originalContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function detectAndPrefillApiBaseUrl(callback) {
|
||||
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
|
||||
const tab = tabs && tabs[0];
|
||||
if (!tab || !tab.url) {
|
||||
if (callback) callback();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const url = new URL(tab.url);
|
||||
const isTrackeepDomain = url.hostname.includes('trackeep') || url.hostname === 'localhost';
|
||||
if (isTrackeepDomain && (url.protocol === 'https:' || url.protocol === 'http:')) {
|
||||
const candidate = `${url.origin}/api/v1`;
|
||||
chrome.storage.sync.get(['trackeepApiBaseUrl'], (items) => {
|
||||
if (!items.trackeepApiBaseUrl) {
|
||||
apiBaseUrlInput.value = candidate;
|
||||
}
|
||||
if (callback) callback();
|
||||
});
|
||||
} else {
|
||||
// Fallback to localhost if nothing set
|
||||
chrome.storage.sync.get(['trackeepApiBaseUrl'], (items) => {
|
||||
if (!items.trackeepApiBaseUrl) {
|
||||
apiBaseUrlInput.value = 'http://localhost:8080/api/v1';
|
||||
}
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
if (callback) callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadSettings() {
|
||||
chrome.storage.sync.get(['trackeepApiBaseUrl', 'trackeepAuthToken'], (items) => {
|
||||
if (items.trackeepApiBaseUrl) {
|
||||
apiBaseUrlInput.value = items.trackeepApiBaseUrl;
|
||||
}
|
||||
if (items.trackeepAuthToken) {
|
||||
authTokenInput.value = items.trackeepAuthToken;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function saveSettings() {
|
||||
const apiBaseUrl = apiBaseUrlInput.value.trim();
|
||||
const authToken = authTokenInput.value.trim();
|
||||
|
||||
if (!apiBaseUrl) {
|
||||
showMessage('API base URL is required.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!authToken) {
|
||||
showMessage('Authentication token is required.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
setButtonLoading(saveBtn, true);
|
||||
hideMessage();
|
||||
|
||||
chrome.storage.sync.set(
|
||||
{
|
||||
trackeepApiBaseUrl: apiBaseUrl,
|
||||
trackeepAuthToken: authToken
|
||||
},
|
||||
() => {
|
||||
setButtonLoading(saveBtn, false);
|
||||
if (chrome.runtime.lastError) {
|
||||
showMessage(`Failed to save: ${chrome.runtime.lastError.message}`, 'error');
|
||||
} else {
|
||||
showMessage(`
|
||||
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="20,6 9,17 4,12"/>
|
||||
</svg>
|
||||
Settings saved successfully! You can now use the extension to save bookmarks and files.
|
||||
`, 'success');
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Initialize everything when DOM is loaded
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
detectAndPrefillApiBaseUrl(() => {
|
||||
loadSettings();
|
||||
saveBtn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
saveSettings();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,880 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-kb-theme="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Trackeep Saver</title>
|
||||
<style>
|
||||
/* Modern Inter Font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
||||
|
||||
/* Modern CSS Variables - Proton Pass Inspired */
|
||||
:root {
|
||||
--bg-primary: #0f0f0f;
|
||||
--bg-secondary: #1a1a1a;
|
||||
--bg-tertiary: #262626;
|
||||
--bg-hover: #2a2a2a;
|
||||
--bg-active: #333333;
|
||||
--border-primary: #2a2a2a;
|
||||
--border-secondary: #333333;
|
||||
--text-primary: #ffffff;
|
||||
--text-secondary: #a3a3a3;
|
||||
--text-tertiary: #737373;
|
||||
--accent-primary: #3b82f6;
|
||||
--accent-hover: #2563eb;
|
||||
--success: #10b981;
|
||||
--warning: #f59e0b;
|
||||
--error: #ef4444;
|
||||
--gradient-primary: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
--gradient-secondary: linear-gradient(135deg, #1a1a1a 0%, #262626 100%);
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5);
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 8px;
|
||||
--radius-lg: 12px;
|
||||
--radius-xl: 16px;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-width: 400px;
|
||||
max-width: 440px;
|
||||
background: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
line-height: 1.5;
|
||||
font-size: 14px;
|
||||
color-scheme: dark;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.header {
|
||||
background: var(--gradient-secondary);
|
||||
padding: 20px 20px 16px;
|
||||
border-bottom: 1px solid var(--border-primary);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.header::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: var(--gradient-primary);
|
||||
}
|
||||
|
||||
.header-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* Enhanced logo animation */
|
||||
.logo {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--gradient-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
box-shadow: var(--shadow-md);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
transform: scale(1.05) rotate(5deg);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.logo::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: linear-gradient(45deg, transparent, rgba(255,255,255,0.1), transparent);
|
||||
transform: rotate(45deg);
|
||||
animation: shimmer 3s infinite;
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); }
|
||||
100% { transform: translateX(100%) translateY(100%) rotate(45deg); }
|
||||
}
|
||||
|
||||
/* Enhanced options button */
|
||||
.options-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--bg-tertiary);
|
||||
border: 1px solid var(--border-primary);
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.options-btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
background: var(--accent-primary);
|
||||
border-radius: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
transition: all 0.3s ease;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
.options-btn:hover {
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
border-color: var(--accent-primary);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.options-btn:hover::before {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Status Bar */
|
||||
.status-bar {
|
||||
padding: 8px 20px;
|
||||
background: var(--bg-secondary);
|
||||
border-bottom: 1px solid var(--border-primary);
|
||||
min-height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: var(--text-tertiary);
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
.status-indicator.connected {
|
||||
background: var(--success);
|
||||
}
|
||||
|
||||
.status-indicator.error {
|
||||
background: var(--error);
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Main Content */
|
||||
.content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
margin-bottom: 20px;
|
||||
background: var(--bg-secondary);
|
||||
padding: 4px;
|
||||
border-radius: var(--radius-lg);
|
||||
border: 1px solid var(--border-primary);
|
||||
}
|
||||
|
||||
.tab {
|
||||
flex: 1;
|
||||
padding: 10px 16px;
|
||||
border-radius: var(--radius-md);
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.tab:hover {
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
background: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
box-shadow: var(--shadow-sm);
|
||||
border: 1px solid var(--border-secondary);
|
||||
}
|
||||
|
||||
.tab-icon {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Tab Content */
|
||||
.tab-content {
|
||||
display: none;
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
.tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
/* Form Sections */
|
||||
.form-section {
|
||||
background: var(--bg-secondary);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 20px;
|
||||
border: 1px solid var(--border-primary);
|
||||
margin-bottom: 16px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.form-section:hover {
|
||||
border-color: var(--border-secondary);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.section-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--gradient-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Form Elements */
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.form-group:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 6px;
|
||||
color: var(--text-secondary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.form-group:focus-within label {
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="url"],
|
||||
input[type="file"],
|
||||
textarea {
|
||||
width: 100%;
|
||||
padding: 12px 14px;
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid var(--border-primary);
|
||||
background: var(--bg-tertiary);
|
||||
color: var(--text-primary);
|
||||
font-size: 13px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 400;
|
||||
transition: all 0.2s ease;
|
||||
outline: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
input[type="text"]:hover,
|
||||
input[type="url"]:hover,
|
||||
textarea:hover {
|
||||
border-color: var(--border-secondary);
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="url"]:focus,
|
||||
textarea:focus {
|
||||
border-color: var(--accent-primary);
|
||||
background: var(--bg-hover);
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
input[type="file"]:hover {
|
||||
border-color: var(--accent-primary);
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
min-height: 80px;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
/* Input field icons */
|
||||
.input-icon {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--text-tertiary);
|
||||
font-size: 14px;
|
||||
pointer-events: none;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.form-group:focus-within .input-icon {
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
|
||||
/* Checkbox */
|
||||
.checkbox-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
background: var(--bg-tertiary);
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid var(--border-primary);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.checkbox-group:hover {
|
||||
background: var(--bg-hover);
|
||||
border-color: var(--border-secondary);
|
||||
}
|
||||
|
||||
.checkbox-group input[type="checkbox"] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
accent-color: var(--accent-primary);
|
||||
}
|
||||
|
||||
.checkbox-label {
|
||||
font-size: 13px;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
font-weight: 400;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
padding: 12px 20px;
|
||||
border-radius: var(--radius-md);
|
||||
border: none;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
font-family: 'Inter', sans-serif;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
outline: none;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.btn:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--gradient-primary);
|
||||
color: white;
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.btn-primary:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--bg-tertiary);
|
||||
color: var(--text-primary);
|
||||
border: 1px solid var(--border-primary);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: var(--bg-hover);
|
||||
border-color: var(--border-secondary);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
transform: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.btn-block {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Enhanced status bar animations */
|
||||
.status-bar {
|
||||
padding: 8px 20px;
|
||||
background: var(--bg-secondary);
|
||||
border-bottom: 1px solid var(--border-primary);
|
||||
min-height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.status-bar:hover {
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
/* Enhanced tab animations */
|
||||
.tab {
|
||||
flex: 1;
|
||||
padding: 10px 16px;
|
||||
border-radius: var(--radius-md);
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
background: var(--accent-primary);
|
||||
transition: all 0.3s ease;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.tab:hover {
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.tab:hover::after {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
background: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
box-shadow: var(--shadow-sm);
|
||||
border: 1px solid var(--border-secondary);
|
||||
}
|
||||
|
||||
.tab.active::after {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
/* Status Messages */
|
||||
.status-message {
|
||||
padding: 12px 16px;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
animation: slideUp 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.status-message.success {
|
||||
background: rgba(16, 185, 129, 0.1);
|
||||
color: var(--success);
|
||||
border: 1px solid rgba(16, 185, 129, 0.2);
|
||||
}
|
||||
|
||||
.status-message.error {
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
color: var(--error);
|
||||
border: 1px solid rgba(239, 68, 68, 0.2);
|
||||
}
|
||||
|
||||
.status-message.info {
|
||||
background: rgba(59, 130, 246, 0.1);
|
||||
color: var(--accent-primary);
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
|
||||
/* Icon System */
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.icon-sm {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.icon-lg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.icon-xl {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
/* Icon animations */
|
||||
.icon-spin {
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
.icon-pulse {
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; transform: scale(1); }
|
||||
50% { opacity: 0.8; transform: scale(1.05); }
|
||||
}
|
||||
|
||||
/* Enhanced button icons */
|
||||
.btn .icon {
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.btn:hover .icon {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.btn:active .icon {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* Tab icon enhancements */
|
||||
.tab .icon {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.tab:hover .icon {
|
||||
transform: translateY(-1px) scale(1.1);
|
||||
}
|
||||
|
||||
.tab.active .icon {
|
||||
color: var(--accent-primary);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
/* Section icon enhancements */
|
||||
.section-icon {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.form-section:hover .section-icon {
|
||||
transform: scale(1.05);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
/* Status indicator enhancements */
|
||||
.status-indicator {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.status-indicator.connected {
|
||||
box-shadow: 0 0 8px rgba(16, 185, 129, 0.5);
|
||||
}
|
||||
|
||||
.status-indicator.error {
|
||||
box-shadow: 0 0 8px rgba(239, 68, 68, 0.5);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 420px) {
|
||||
body {
|
||||
min-width: 360px;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.form-section {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header -->
|
||||
<header class="header">
|
||||
<div class="header-content">
|
||||
<div class="logo-container">
|
||||
<div class="logo">T</div>
|
||||
<h1 class="title">Trackeep</h1>
|
||||
</div>
|
||||
<button class="options-btn" id="openOptions" title="Settings">
|
||||
<svg class="icon icon-lg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
<path d="M12 1v6m0 6v6m4.22-13.22l4.24 4.24M1.54 1.54l4.24 4.24M1 12h6m6 0h6"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Status Bar -->
|
||||
<div class="status-bar">
|
||||
<div class="status-indicator" id="statusIndicator"></div>
|
||||
<div class="status-text" id="statusText">Checking configuration...</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="content">
|
||||
<!-- Tabs -->
|
||||
<div class="tabs">
|
||||
<button class="tab active" data-tab="bookmark">
|
||||
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/>
|
||||
</svg>
|
||||
<span>Bookmark</span>
|
||||
</button>
|
||||
<button class="tab" data-tab="file">
|
||||
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
||||
<polyline points="14,2 14,8 20,8"/>
|
||||
</svg>
|
||||
<span>File</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Bookmark Tab -->
|
||||
<div class="tab-content active" id="bookmark-tab">
|
||||
<div class="form-section">
|
||||
<div class="section-header">
|
||||
<div class="section-icon">
|
||||
<svg class="icon-xl" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
|
||||
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="section-title">Save Current Page</h2>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="bookmarkTitle">Title</label>
|
||||
<input id="bookmarkTitle" type="text" placeholder="Page title will be auto-filled" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="bookmarkUrl">URL</label>
|
||||
<input id="bookmarkUrl" type="url" placeholder="https://example.com" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="bookmarkDescription">Description</label>
|
||||
<textarea id="bookmarkDescription" placeholder="Why is this page important? Add notes..."></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="bookmarkTags">Tags</label>
|
||||
<input id="bookmarkTags" type="text" placeholder="reading, development, tutorial" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="checkbox-group">
|
||||
<input id="bookmarkPublic" type="checkbox" />
|
||||
<label for="bookmarkPublic" class="checkbox-label">Make this bookmark public</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<div></div>
|
||||
<button class="btn btn-primary" id="saveBookmarkBtn">
|
||||
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
|
||||
<polyline points="17,21 17,13 7,13 7,21"/>
|
||||
<polyline points="7,3 7,8 15,8"/>
|
||||
</svg>
|
||||
<span>Save Bookmark</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- File Tab -->
|
||||
<div class="tab-content" id="file-tab">
|
||||
<div class="form-section">
|
||||
<div class="section-header">
|
||||
<div class="section-icon">
|
||||
<svg class="icon-xl" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="17,8 12,3 7,8"/>
|
||||
<line x1="12" y1="3" x2="12" y2="15"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="section-title">Upload File</h2>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="fileInput">Choose File</label>
|
||||
<input id="fileInput" type="file" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="fileDescription">Description</label>
|
||||
<textarea id="fileDescription" placeholder="Describe this file..."></textarea>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary btn-block" id="uploadFileBtn">
|
||||
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="17,8 12,3 7,8"/>
|
||||
<line x1="12" y1="3" x2="12" y2="15"/>
|
||||
</svg>
|
||||
<span>Upload File</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Status Message -->
|
||||
<div id="statusMessage" class="status-message" style="display: none;"></div>
|
||||
</main>
|
||||
|
||||
<script src="popup.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,192 +0,0 @@
|
||||
# Trackeep Mobile App
|
||||
|
||||
React Native mobile application for Trackeep - productivity and knowledge management platform.
|
||||
|
||||
## Features
|
||||
|
||||
### ✅ Core Features Implemented
|
||||
- **🔐 Authentication**: Login with email/password and GitHub OAuth
|
||||
- **📱 Offline Support**: Full offline functionality with sync when online
|
||||
- **📝 Content Management**: Bookmarks, Tasks, Notes, and Time Tracking
|
||||
- **🔍 Search**: Unified search across all content types
|
||||
- **⏱️ Time Tracking**: Built-in timer with task association
|
||||
- **🎨 Modern UI**: Material Design with React Native Paper
|
||||
- **📊 Dashboard**: Overview with stats and recent activity
|
||||
|
||||
### ✅ Mobile-Specific Features
|
||||
- **Gesture Navigation**: Intuitive mobile navigation patterns
|
||||
- **Push Notifications**: Task reminders and updates with permission management
|
||||
- **Camera Integration**: Document scanning capability with permission handling
|
||||
- **Voice Notes**: Audio recording for quick notes with speech-to-text
|
||||
- **Background Sync**: Automatic data synchronization
|
||||
- **Responsive Design**: Optimized for various screen sizes
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **React Native** 0.72.6
|
||||
- **TypeScript** for type safety
|
||||
- **React Navigation** for navigation
|
||||
- **React Native Paper** for UI components
|
||||
- **AsyncStorage** for local data persistence
|
||||
- **Axios** for API communication
|
||||
- **Vector Icons** for iconography
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
mobile-app/
|
||||
├── src/
|
||||
│ ├── components/ # Reusable UI components
|
||||
│ ├── screens/ # Screen components
|
||||
│ │ ├── auth/ # Authentication screens
|
||||
│ │ ├── DashboardScreen.tsx
|
||||
│ │ ├── BookmarksScreen.tsx
|
||||
│ │ ├── TasksScreen.tsx
|
||||
│ │ ├── NotesScreen.tsx
|
||||
│ │ ├── TimeTrackingScreen.tsx
|
||||
│ │ ├── SearchScreen.tsx
|
||||
│ │ └── SettingsScreen.tsx
|
||||
│ ├── services/ # Business logic and API
|
||||
│ │ ├── AuthContext.tsx
|
||||
│ │ ├── OfflineContext.tsx
|
||||
│ │ └── api.ts
|
||||
│ ├── navigation/ # Navigation configuration
|
||||
│ ├── utils/ # Utility functions
|
||||
│ │ ├── storage.ts
|
||||
│ │ └── offlineSync.ts
|
||||
│ └── types/ # TypeScript type definitions
|
||||
├── android/ # Android-specific code
|
||||
├── ios/ # iOS-specific code
|
||||
└── package.json
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 16+
|
||||
- React Native CLI
|
||||
- Android Studio (for Android development)
|
||||
- Xcode (for iOS development)
|
||||
|
||||
### Installation
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd Trackeep/mobile-app
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
3. For iOS, install pods:
|
||||
```bash
|
||||
cd ios && pod install && cd ..
|
||||
```
|
||||
|
||||
### Running the App
|
||||
|
||||
#### Android
|
||||
```bash
|
||||
npm run android
|
||||
```
|
||||
|
||||
#### iOS
|
||||
```bash
|
||||
npm run ios
|
||||
```
|
||||
|
||||
#### Start Metro Bundler
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Create a `.env` file in the root directory:
|
||||
|
||||
```env
|
||||
API_BASE_URL=http://localhost:8080/api
|
||||
```
|
||||
|
||||
### API Configuration
|
||||
|
||||
Update the API base URL in `src/services/api.ts` to match your backend server.
|
||||
|
||||
## Features Status
|
||||
|
||||
### ✅ Completed
|
||||
- [x] Project setup and configuration
|
||||
- [x] Authentication flow (email/password, GitHub)
|
||||
- [x] Navigation structure
|
||||
- [x] Core screens (Dashboard, Bookmarks, Tasks, Notes, Time Tracking, Search, Settings)
|
||||
- [x] Offline data storage and sync
|
||||
- [x] Modern UI with Material Design
|
||||
- [x] TypeScript integration
|
||||
- [x] API service layer
|
||||
- [x] Push notification implementation with permission management
|
||||
- [x] Camera integration for document scanning
|
||||
- [x] Voice recording for notes with speech-to-text
|
||||
- [x] Enhanced settings screen with mobile features
|
||||
|
||||
### 📋 Planned
|
||||
- [ ] Biometric authentication
|
||||
- [ ] Dark mode theme
|
||||
- [ ] Widget support
|
||||
- [ ] Apple Watch companion app
|
||||
- [ ] Advanced analytics
|
||||
|
||||
## Development
|
||||
|
||||
### Code Style
|
||||
|
||||
The project uses TypeScript and follows React Native best practices. All components are functional components with hooks.
|
||||
|
||||
### State Management
|
||||
|
||||
- **Authentication**: React Context (AuthContext)
|
||||
- **Offline Sync**: React Context (OfflineContext)
|
||||
- **Local Data**: AsyncStorage with SQLite for complex queries
|
||||
|
||||
### API Integration
|
||||
|
||||
All API calls are centralized in `src/services/api.ts` with automatic token management and error handling.
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
### Android Release Build
|
||||
```bash
|
||||
npm run build:android
|
||||
```
|
||||
|
||||
### iOS Release Build
|
||||
```bash
|
||||
npm run build:ios
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Add tests if applicable
|
||||
5. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License.
|
||||
|
||||
## Support
|
||||
|
||||
For support and questions, please open an issue in the repository.
|
||||
@@ -1,210 +0,0 @@
|
||||
# Mobile App Sync Testing Guide
|
||||
|
||||
## Overview
|
||||
This guide helps you test the bi-directional synchronization between the Trackeep mobile app and web dashboard.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Backend Server**: Ensure your Trackeep backend is running
|
||||
2. **Web Dashboard**: Access the web dashboard at `http://localhost:3000` (or your configured URL)
|
||||
3. **Mobile App**: Run the React Native app using:
|
||||
```bash
|
||||
npm start
|
||||
npm run android # or npm run ios
|
||||
```
|
||||
|
||||
## First Launch Setup
|
||||
|
||||
1. **Server Configuration**: On first launch, the mobile app will show the server setup screen:
|
||||
- Enter your backend URL (e.g., `http://localhost:8080`)
|
||||
- Enter your credentials
|
||||
- Test connection before completing setup
|
||||
|
||||
2. **Authentication**: After setup, you'll be redirected to login with your existing credentials
|
||||
|
||||
## Testing Real-Time Sync
|
||||
|
||||
### Test 1: Create Content on Mobile, Verify on Web
|
||||
|
||||
1. **On Mobile App**:
|
||||
- Open the Dashboard
|
||||
- Tap the FAB (+) button
|
||||
- Create a new task, bookmark, or note
|
||||
- Verify it appears in the mobile dashboard
|
||||
|
||||
2. **On Web Dashboard**:
|
||||
- Navigate to the corresponding section (Tasks, Bookmarks, or Notes)
|
||||
- The new item should appear within seconds (if WebSocket is connected)
|
||||
- If not, refresh the page to see the synced item
|
||||
|
||||
### Test 2: Create Content on Web, Verify on Mobile
|
||||
|
||||
1. **On Web Dashboard**:
|
||||
- Create a new task, bookmark, or note
|
||||
- Save the item
|
||||
|
||||
2. **On Mobile App**:
|
||||
- The item should appear automatically if real-time sync is working
|
||||
- Pull to refresh on the dashboard to force sync
|
||||
- Check the specific section to verify the item appears
|
||||
|
||||
### Test 3: Offline Mode Testing
|
||||
|
||||
1. **Enable Offline Mode**:
|
||||
- Turn off internet connection on your mobile device
|
||||
- The app should show "🔴 Offline" status
|
||||
|
||||
2. **Create Content Offline**:
|
||||
- Create several tasks, bookmarks, or notes
|
||||
- Notice the pending changes counter increases
|
||||
|
||||
3. **Restore Connection**:
|
||||
- Turn internet back on
|
||||
- App should show "🟢 Connected" and auto-sync
|
||||
- Verify items appear on web dashboard
|
||||
|
||||
### Test 4: Conflict Resolution
|
||||
|
||||
1. **Simulate Conflict**:
|
||||
- Create the same item on both mobile and web while offline
|
||||
- Bring both online simultaneously
|
||||
- Verify how conflicts are resolved (last write wins or merge)
|
||||
|
||||
## Key Features to Test
|
||||
|
||||
### Real-Time Updates
|
||||
- ✅ WebSocket connection status
|
||||
- ✅ Instant updates across devices
|
||||
- ✅ Connection recovery after disconnection
|
||||
|
||||
### Offline Support
|
||||
- ✅ Offline data persistence
|
||||
- ✅ Pending changes tracking
|
||||
- ✅ Automatic sync when online
|
||||
- ✅ Manual sync button
|
||||
|
||||
### Data Integrity
|
||||
- ✅ All data types sync correctly (tasks, bookmarks, notes)
|
||||
- ✅ Timestamps preserved
|
||||
- ✅ User associations maintained
|
||||
- ✅ Tags and metadata sync
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **WebSocket Connection Failed**:
|
||||
- Check if backend WebSocket endpoint is accessible
|
||||
- Verify firewall settings
|
||||
- Check browser console for WebSocket errors
|
||||
|
||||
2. **Sync Not Working**:
|
||||
- Verify server URL in mobile app settings
|
||||
- Check authentication tokens
|
||||
- Review backend logs for sync errors
|
||||
|
||||
3. **Offline Mode Not Detected**:
|
||||
- Check network permissions on mobile device
|
||||
- Verify NetInfo plugin is working
|
||||
- Test with airplane mode
|
||||
|
||||
### Debug Tools
|
||||
|
||||
1. **Mobile App Debugging**:
|
||||
```bash
|
||||
# Enable debug mode
|
||||
npx react-native log-android
|
||||
npx react-native log-ios
|
||||
```
|
||||
|
||||
2. **Backend Logs**:
|
||||
- Monitor sync endpoint logs
|
||||
- Check WebSocket connection logs
|
||||
- Review database transaction logs
|
||||
|
||||
3. **Browser Console**:
|
||||
- Monitor WebSocket connections
|
||||
- Check for real-time update events
|
||||
- Verify API responses
|
||||
|
||||
## Performance Testing
|
||||
|
||||
### Test Scenarios
|
||||
|
||||
1. **Large Dataset Sync**:
|
||||
- Create 100+ items on one device
|
||||
- Measure sync time to other device
|
||||
- Verify no data loss
|
||||
|
||||
2. **Concurrent Updates**:
|
||||
- Multiple users updating same data
|
||||
- Test conflict resolution
|
||||
- Verify data consistency
|
||||
|
||||
3. **Network Conditions**:
|
||||
- Test on slow networks (2G/3G)
|
||||
- Test with intermittent connectivity
|
||||
- Verify sync resilience
|
||||
|
||||
## Expected Results
|
||||
|
||||
### Successful Sync Indicators
|
||||
|
||||
1. **Mobile App**:
|
||||
- Status shows "🟢 Connected"
|
||||
- Last sync time updates
|
||||
- No pending changes counter
|
||||
- Real-time updates received
|
||||
|
||||
2. **Web Dashboard**:
|
||||
- New items appear without refresh
|
||||
- WebSocket connection established
|
||||
- No sync errors in console
|
||||
|
||||
### Performance Benchmarks
|
||||
|
||||
- **Small items** (< 1KB): Should sync within 1-2 seconds
|
||||
- **Large items** (> 100KB): Should sync within 5-10 seconds
|
||||
- **Batch sync** (50+ items): Should complete within 30 seconds
|
||||
|
||||
## Automated Testing
|
||||
|
||||
For comprehensive testing, consider implementing:
|
||||
|
||||
1. **Unit Tests**:
|
||||
- Sync logic validation
|
||||
- Offline queue management
|
||||
- Conflict resolution
|
||||
|
||||
2. **Integration Tests**:
|
||||
- End-to-end sync workflows
|
||||
- WebSocket connection testing
|
||||
- API integration validation
|
||||
|
||||
3. **E2E Tests**:
|
||||
- Multi-device sync scenarios
|
||||
- Offline/online transitions
|
||||
- User interaction flows
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
When reporting sync issues, include:
|
||||
|
||||
1. Device information (OS, version)
|
||||
2. Network conditions
|
||||
3. Steps to reproduce
|
||||
4. Screenshots of error messages
|
||||
5. Backend logs (if available)
|
||||
6. Browser console errors
|
||||
|
||||
## Success Criteria
|
||||
|
||||
The sync implementation is considered successful when:
|
||||
|
||||
- ✅ All data types sync bi-directionally
|
||||
- ✅ Real-time updates work within 5 seconds
|
||||
- ✅ Offline mode functions correctly
|
||||
- ✅ No data loss during sync
|
||||
- ✅ Conflicts are handled gracefully
|
||||
- ✅ Performance meets benchmarks
|
||||
- ✅ Error recovery works reliably
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1024 1024">
|
||||
<!-- Generator: Adobe Illustrator 29.7.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 8) -->
|
||||
<path fill="#3b82f6" d="M797.56,348.33c30.91,6.66,83.06,31.07,87.21,66.41,3.15,26.85-13.06,79.89-19.48,108.33-18.08,80.05-35.49,169.43-58.24,247.51-37.84,129.87-259.97,143.84-369.81,131-79.98-9.34-191.79-42.13-218.72-127.8l-79.09-341.68c-6.97-50.68,49.68-73.96,89.21-85.61,54.67-16.12,110.4-16.62,167.08-15.62l-45.47,16.39c-44.91,18.53-101.62,26.35-145.23,45.5-15.84,6.96-26.94,19.89-14.58,36.36,18.56,24.72,115.14,56.1,146.77,62.89,82.16,17.65,152.89,2.18,231.43-22.46,54.98-17.25,130.36-44.86,168.52-89.18,25.27-29.35,31.42-69.3,44.38-104.84l-243.09,42.99-2,3.82c-1.45,15.08-2.76,30.11-6.03,44.92-31.75,143.69-186.99,93.71-283.19,53.84l1.47-2.15c82.39-23.86,163.75-50.91,245.03-78.2,5.91-3.48,5.08-25.81,7.22-33.55,3.45-12.47,12.22-19.65,23.97-24.08l282.88-49.24c14.15,3.11,20.4,11.87,18.9,26.37l-29.13,88.06v.02ZM841.24,457.54l-19.61,14.59c-113.51,75.99-355.25,76.96-485.87,53.37-58.02-10.48-91.56-24.33-143.96-48.22-1.22-.56-3.68-1.88-4.26-.11,9.51,23.92,8.86,56.35,22.36,78.1,28.12,45.3,113.96,67.69,163.71,76.52,72.61,12.88,148.98,14.98,222.29,7.73,63.62-6.3,204.67-30.25,226.3-101.29,7.88-25.88,11.16-54.64,19.03-80.69h0ZM806.3,607.51l-30.5,18.26c-131.73,66.26-405.38,65.51-535.38-4.91-6.49-3.51-12.31-8.25-18.62-11.96-1.12-.66-2.56-2.94-3.72-.65,11.55,32.54,8.2,71.49,34.17,96.87,59.84,58.47,212.94,70.07,292.78,66.97,63.99-2.48,191.09-21.71,233.65-73.56,19.02-23.17,17.88-63.15,27.62-91.02h0ZM774.26,744.37c-13.76,6.59-26.7,15.08-40.78,21.08-119.06,50.77-329.26,50.83-447.48-2.37-12.39-5.57-23.46-13.36-35.88-18.71,6.11,30.5,22.34,54.66,47.59,72.51,97.85,69.2,342.24,69.95,436.47-5.6,21.95-17.59,34.7-39.15,40.08-66.92h0Z"/>
|
||||
<rect fill="#3b82f6" x="468.16" y="171.76" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="593.35" y="118.61" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="361.93" y="250.32" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1024 1024">
|
||||
<!-- Generator: Adobe Illustrator 29.7.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 8) -->
|
||||
<path fill="#3b82f6" d="M797.56,348.33c30.91,6.66,83.06,31.07,87.21,66.41,3.15,26.85-13.06,79.89-19.48,108.33-18.08,80.05-35.49,169.43-58.24,247.51-37.84,129.87-259.97,143.84-369.81,131-79.98-9.34-191.79-42.13-218.72-127.8l-79.09-341.68c-6.97-50.68,49.68-73.96,89.21-85.61,54.67-16.12,110.4-16.62,167.08-15.62l-45.47,16.39c-44.91,18.53-101.62,26.35-145.23,45.5-15.84,6.96-26.94,19.89-14.58,36.36,18.56,24.72,115.14,56.1,146.77,62.89,82.16,17.65,152.89,2.18,231.43-22.46,54.98-17.25,130.36-44.86,168.52-89.18,25.27-29.35,31.42-69.3,44.38-104.84l-243.09,42.99-2,3.82c-1.45,15.08-2.76,30.11-6.03,44.92-31.75,143.69-186.99,93.71-283.19,53.84l1.47-2.15c82.39-23.86,163.75-50.91,245.03-78.2,5.91-3.48,5.08-25.81,7.22-33.55,3.45-12.47,12.22-19.65,23.97-24.08l282.88-49.24c14.15,3.11,20.4,11.87,18.9,26.37l-29.13,88.06v.02ZM841.24,457.54l-19.61,14.59c-113.51,75.99-355.25,76.96-485.87,53.37-58.02-10.48-91.56-24.33-143.96-48.22-1.22-.56-3.68-1.88-4.26-.11,9.51,23.92,8.86,56.35,22.36,78.1,28.12,45.3,113.96,67.69,163.71,76.52,72.61,12.88,148.98,14.98,222.29,7.73,63.62-6.3,204.67-30.25,226.3-101.29,7.88-25.88,11.16-54.64,19.03-80.69h0ZM806.3,607.51l-30.5,18.26c-131.73,66.26-405.38,65.51-535.38-4.91-6.49-3.51-12.31-8.25-18.62-11.96-1.12-.66-2.56-2.94-3.72-.65,11.55,32.54,8.2,71.49,34.17,96.87,59.84,58.47,212.94,70.07,292.78,66.97,63.99-2.48,191.09-21.71,233.65-73.56,19.02-23.17,17.88-63.15,27.62-91.02h0ZM774.26,744.37c-13.76,6.59-26.7,15.08-40.78,21.08-119.06,50.77-329.26,50.83-447.48-2.37-12.39-5.57-23.46-13.36-35.88-18.71,6.11,30.5,22.34,54.66,47.59,72.51,97.85,69.2,342.24,69.95,436.47-5.6,21.95-17.59,34.7-39.15,40.08-66.92h0Z"/>
|
||||
<rect fill="#3b82f6" x="468.16" y="171.76" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="593.35" y="118.61" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="361.93" y="250.32" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1024 1024">
|
||||
<!-- Generator: Adobe Illustrator 29.7.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 8) -->
|
||||
<path fill="#3b82f6" d="M797.56,348.33c30.91,6.66,83.06,31.07,87.21,66.41,3.15,26.85-13.06,79.89-19.48,108.33-18.08,80.05-35.49,169.43-58.24,247.51-37.84,129.87-259.97,143.84-369.81,131-79.98-9.34-191.79-42.13-218.72-127.8l-79.09-341.68c-6.97-50.68,49.68-73.96,89.21-85.61,54.67-16.12,110.4-16.62,167.08-15.62l-45.47,16.39c-44.91,18.53-101.62,26.35-145.23,45.5-15.84,6.96-26.94,19.89-14.58,36.36,18.56,24.72,115.14,56.1,146.77,62.89,82.16,17.65,152.89,2.18,231.43-22.46,54.98-17.25,130.36-44.86,168.52-89.18,25.27-29.35,31.42-69.3,44.38-104.84l-243.09,42.99-2,3.82c-1.45,15.08-2.76,30.11-6.03,44.92-31.75,143.69-186.99,93.71-283.19,53.84l1.47-2.15c82.39-23.86,163.75-50.91,245.03-78.2,5.91-3.48,5.08-25.81,7.22-33.55,3.45-12.47,12.22-19.65,23.97-24.08l282.88-49.24c14.15,3.11,20.4,11.87,18.9,26.37l-29.13,88.06v.02ZM841.24,457.54l-19.61,14.59c-113.51,75.99-355.25,76.96-485.87,53.37-58.02-10.48-91.56-24.33-143.96-48.22-1.22-.56-3.68-1.88-4.26-.11,9.51,23.92,8.86,56.35,22.36,78.1,28.12,45.3,113.96,67.69,163.71,76.52,72.61,12.88,148.98,14.98,222.29,7.73,63.62-6.3,204.67-30.25,226.3-101.29,7.88-25.88,11.16-54.64,19.03-80.69h0ZM806.3,607.51l-30.5,18.26c-131.73,66.26-405.38,65.51-535.38-4.91-6.49-3.51-12.31-8.25-18.62-11.96-1.12-.66-2.56-2.94-3.72-.65,11.55,32.54,8.2,71.49,34.17,96.87,59.84,58.47,212.94,70.07,292.78,66.97,63.99-2.48,191.09-21.71,233.65-73.56,19.02-23.17,17.88-63.15,27.62-91.02h0ZM774.26,744.37c-13.76,6.59-26.7,15.08-40.78,21.08-119.06,50.77-329.26,50.83-447.48-2.37-12.39-5.57-23.46-13.36-35.88-18.71,6.11,30.5,22.34,54.66,47.59,72.51,97.85,69.2,342.24,69.95,436.47-5.6,21.95-17.59,34.7-39.15,40.08-66.92h0Z"/>
|
||||
<rect fill="#3b82f6" x="468.16" y="171.76" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="593.35" y="118.61" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="361.93" y="250.32" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "Trackeep",
|
||||
"displayName": "Trackeep",
|
||||
"version": "1.0.0",
|
||||
"description": "Productivity and knowledge management mobile app"
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
module.exports = {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
plugins: [
|
||||
[
|
||||
'module-resolver',
|
||||
{
|
||||
root: ['./src'],
|
||||
extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
|
||||
alias: {
|
||||
'@': './src',
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* Trackeep Mobile App
|
||||
* React Native entry point
|
||||
*/
|
||||
import {AppRegistry} from 'react-native';
|
||||
import App from './src/App';
|
||||
import {name as appName} from './app.json';
|
||||
|
||||
AppRegistry.registerComponent(appName, () => App);
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1024 1024">
|
||||
<!-- Generator: Adobe Illustrator 29.7.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 8) -->
|
||||
<path fill="#3b82f6" d="M797.56,348.33c30.91,6.66,83.06,31.07,87.21,66.41,3.15,26.85-13.06,79.89-19.48,108.33-18.08,80.05-35.49,169.43-58.24,247.51-37.84,129.87-259.97,143.84-369.81,131-79.98-9.34-191.79-42.13-218.72-127.8l-79.09-341.68c-6.97-50.68,49.68-73.96,89.21-85.61,54.67-16.12,110.4-16.62,167.08-15.62l-45.47,16.39c-44.91,18.53-101.62,26.35-145.23,45.5-15.84,6.96-26.94,19.89-14.58,36.36,18.56,24.72,115.14,56.1,146.77,62.89,82.16,17.65,152.89,2.18,231.43-22.46,54.98-17.25,130.36-44.86,168.52-89.18,25.27-29.35,31.42-69.3,44.38-104.84l-243.09,42.99-2,3.82c-1.45,15.08-2.76,30.11-6.03,44.92-31.75,143.69-186.99,93.71-283.19,53.84l1.47-2.15c82.39-23.86,163.75-50.91,245.03-78.2,5.91-3.48,5.08-25.81,7.22-33.55,3.45-12.47,12.22-19.65,23.97-24.08l282.88-49.24c14.15,3.11,20.4,11.87,18.9,26.37l-29.13,88.06v.02ZM841.24,457.54l-19.61,14.59c-113.51,75.99-355.25,76.96-485.87,53.37-58.02-10.48-91.56-24.33-143.96-48.22-1.22-.56-3.68-1.88-4.26-.11,9.51,23.92,8.86,56.35,22.36,78.1,28.12,45.3,113.96,67.69,163.71,76.52,72.61,12.88,148.98,14.98,222.29,7.73,63.62-6.3,204.67-30.25,226.3-101.29,7.88-25.88,11.16-54.64,19.03-80.69h0ZM806.3,607.51l-30.5,18.26c-131.73,66.26-405.38,65.51-535.38-4.91-6.49-3.51-12.31-8.25-18.62-11.96-1.12-.66-2.56-2.94-3.72-.65,11.55,32.54,8.2,71.49,34.17,96.87,59.84,58.47,212.94,70.07,292.78,66.97,63.99-2.48,191.09-21.71,233.65-73.56,19.02-23.17,17.88-63.15,27.62-91.02h0ZM774.26,744.37c-13.76,6.59-26.7,15.08-40.78,21.08-119.06,50.77-329.26,50.83-447.48-2.37-12.39-5.57-23.46-13.36-35.88-18.71,6.11,30.5,22.34,54.66,47.59,72.51,97.85,69.2,342.24,69.95,436.47-5.6,21.95-17.59,34.7-39.15,40.08-66.92h0Z"/>
|
||||
<rect fill="#3b82f6" x="468.16" y="171.76" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="593.35" y="118.61" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="361.93" y="250.32" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1024 1024">
|
||||
<!-- Generator: Adobe Illustrator 29.7.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 8) -->
|
||||
<path fill="#3b82f6" d="M797.56,348.33c30.91,6.66,83.06,31.07,87.21,66.41,3.15,26.85-13.06,79.89-19.48,108.33-18.08,80.05-35.49,169.43-58.24,247.51-37.84,129.87-259.97,143.84-369.81,131-79.98-9.34-191.79-42.13-218.72-127.8l-79.09-341.68c-6.97-50.68,49.68-73.96,89.21-85.61,54.67-16.12,110.4-16.62,167.08-15.62l-45.47,16.39c-44.91,18.53-101.62,26.35-145.23,45.5-15.84,6.96-26.94,19.89-14.58,36.36,18.56,24.72,115.14,56.1,146.77,62.89,82.16,17.65,152.89,2.18,231.43-22.46,54.98-17.25,130.36-44.86,168.52-89.18,25.27-29.35,31.42-69.3,44.38-104.84l-243.09,42.99-2,3.82c-1.45,15.08-2.76,30.11-6.03,44.92-31.75,143.69-186.99,93.71-283.19,53.84l1.47-2.15c82.39-23.86,163.75-50.91,245.03-78.2,5.91-3.48,5.08-25.81,7.22-33.55,3.45-12.47,12.22-19.65,23.97-24.08l282.88-49.24c14.15,3.11,20.4,11.87,18.9,26.37l-29.13,88.06v.02ZM841.24,457.54l-19.61,14.59c-113.51,75.99-355.25,76.96-485.87,53.37-58.02-10.48-91.56-24.33-143.96-48.22-1.22-.56-3.68-1.88-4.26-.11,9.51,23.92,8.86,56.35,22.36,78.1,28.12,45.3,113.96,67.69,163.71,76.52,72.61,12.88,148.98,14.98,222.29,7.73,63.62-6.3,204.67-30.25,226.3-101.29,7.88-25.88,11.16-54.64,19.03-80.69h0ZM806.3,607.51l-30.5,18.26c-131.73,66.26-405.38,65.51-535.38-4.91-6.49-3.51-12.31-8.25-18.62-11.96-1.12-.66-2.56-2.94-3.72-.65,11.55,32.54,8.2,71.49,34.17,96.87,59.84,58.47,212.94,70.07,292.78,66.97,63.99-2.48,191.09-21.71,233.65-73.56,19.02-23.17,17.88-63.15,27.62-91.02h0ZM774.26,744.37c-13.76,6.59-26.7,15.08-40.78,21.08-119.06,50.77-329.26,50.83-447.48-2.37-12.39-5.57-23.46-13.36-35.88-18.71,6.11,30.5,22.34,54.66,47.59,72.51,97.85,69.2,342.24,69.95,436.47-5.6,21.95-17.59,34.7-39.15,40.08-66.92h0Z"/>
|
||||
<rect fill="#3b82f6" x="468.16" y="171.76" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="593.35" y="118.61" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="361.93" y="250.32" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1024 1024">
|
||||
<!-- Generator: Adobe Illustrator 29.7.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 8) -->
|
||||
<path fill="#3b82f6" d="M797.56,348.33c30.91,6.66,83.06,31.07,87.21,66.41,3.15,26.85-13.06,79.89-19.48,108.33-18.08,80.05-35.49,169.43-58.24,247.51-37.84,129.87-259.97,143.84-369.81,131-79.98-9.34-191.79-42.13-218.72-127.8l-79.09-341.68c-6.97-50.68,49.68-73.96,89.21-85.61,54.67-16.12,110.4-16.62,167.08-15.62l-45.47,16.39c-44.91,18.53-101.62,26.35-145.23,45.5-15.84,6.96-26.94,19.89-14.58,36.36,18.56,24.72,115.14,56.1,146.77,62.89,82.16,17.65,152.89,2.18,231.43-22.46,54.98-17.25,130.36-44.86,168.52-89.18,25.27-29.35,31.42-69.3,44.38-104.84l-243.09,42.99-2,3.82c-1.45,15.08-2.76,30.11-6.03,44.92-31.75,143.69-186.99,93.71-283.19,53.84l1.47-2.15c82.39-23.86,163.75-50.91,245.03-78.2,5.91-3.48,5.08-25.81,7.22-33.55,3.45-12.47,12.22-19.65,23.97-24.08l282.88-49.24c14.15,3.11,20.4,11.87,18.9,26.37l-29.13,88.06v.02ZM841.24,457.54l-19.61,14.59c-113.51,75.99-355.25,76.96-485.87,53.37-58.02-10.48-91.56-24.33-143.96-48.22-1.22-.56-3.68-1.88-4.26-.11,9.51,23.92,8.86,56.35,22.36,78.1,28.12,45.3,113.96,67.69,163.71,76.52,72.61,12.88,148.98,14.98,222.29,7.73,63.62-6.3,204.67-30.25,226.3-101.29,7.88-25.88,11.16-54.64,19.03-80.69h0ZM806.3,607.51l-30.5,18.26c-131.73,66.26-405.38,65.51-535.38-4.91-6.49-3.51-12.31-8.25-18.62-11.96-1.12-.66-2.56-2.94-3.72-.65,11.55,32.54,8.2,71.49,34.17,96.87,59.84,58.47,212.94,70.07,292.78,66.97,63.99-2.48,191.09-21.71,233.65-73.56,19.02-23.17,17.88-63.15,27.62-91.02h0ZM774.26,744.37c-13.76,6.59-26.7,15.08-40.78,21.08-119.06,50.77-329.26,50.83-447.48-2.37-12.39-5.57-23.46-13.36-35.88-18.71,6.11,30.5,22.34,54.66,47.59,72.51,97.85,69.2,342.24,69.95,436.47-5.6,21.95-17.59,34.7-39.15,40.08-66.92h0Z"/>
|
||||
<rect fill="#3b82f6" x="468.16" y="171.76" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="593.35" y="118.61" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="361.93" y="250.32" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1024 1024">
|
||||
<!-- Generator: Adobe Illustrator 29.7.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 8) -->
|
||||
<path fill="#3b82f6" d="M797.56,348.33c30.91,6.66,83.06,31.07,87.21,66.41,3.15,26.85-13.06,79.89-19.48,108.33-18.08,80.05-35.49,169.43-58.24,247.51-37.84,129.87-259.97,143.84-369.81,131-79.98-9.34-191.79-42.13-218.72-127.8l-79.09-341.68c-6.97-50.68,49.68-73.96,89.21-85.61,54.67-16.12,110.4-16.62,167.08-15.62l-45.47,16.39c-44.91,18.53-101.62,26.35-145.23,45.5-15.84,6.96-26.94,19.89-14.58,36.36,18.56,24.72,115.14,56.1,146.77,62.89,82.16,17.65,152.89,2.18,231.43-22.46,54.98-17.25,130.36-44.86,168.52-89.18,25.27-29.35,31.42-69.3,44.38-104.84l-243.09,42.99-2,3.82c-1.45,15.08-2.76,30.11-6.03,44.92-31.75,143.69-186.99,93.71-283.19,53.84l1.47-2.15c82.39-23.86,163.75-50.91,245.03-78.2,5.91-3.48,5.08-25.81,7.22-33.55,3.45-12.47,12.22-19.65,23.97-24.08l282.88-49.24c14.15,3.11,20.4,11.87,18.9,26.37l-29.13,88.06v.02ZM841.24,457.54l-19.61,14.59c-113.51,75.99-355.25,76.96-485.87,53.37-58.02-10.48-91.56-24.33-143.96-48.22-1.22-.56-3.68-1.88-4.26-.11,9.51,23.92,8.86,56.35,22.36,78.1,28.12,45.3,113.96,67.69,163.71,76.52,72.61,12.88,148.98,14.98,222.29,7.73,63.62-6.3,204.67-30.25,226.3-101.29,7.88-25.88,11.16-54.64,19.03-80.69h0ZM806.3,607.51l-30.5,18.26c-131.73,66.26-405.38,65.51-535.38-4.91-6.49-3.51-12.31-8.25-18.62-11.96-1.12-.66-2.56-2.94-3.72-.65,11.55,32.54,8.2,71.49,34.17,96.87,59.84,58.47,212.94,70.07,292.78,66.97,63.99-2.48,191.09-21.71,233.65-73.56,19.02-23.17,17.88-63.15,27.62-91.02h0ZM774.26,744.37c-13.76,6.59-26.7,15.08-40.78,21.08-119.06,50.77-329.26,50.83-447.48-2.37-12.39-5.57-23.46-13.36-35.88-18.71,6.11,30.5,22.34,54.66,47.59,72.51,97.85,69.2,342.24,69.95,436.47-5.6,21.95-17.59,34.7-39.15,40.08-66.92h0Z"/>
|
||||
<rect fill="#3b82f6" x="468.16" y="171.76" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="593.35" y="118.61" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
<rect fill="#3b82f6" x="361.93" y="250.32" width="53.15" height="53.15" rx="5.6" ry="5.6"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,21 +0,0 @@
|
||||
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
|
||||
|
||||
const defaultConfig = getDefaultConfig(__dirname);
|
||||
|
||||
const config = {
|
||||
transformer: {
|
||||
getTransformOptions: async () => ({
|
||||
transform: {
|
||||
experimentalImportSupport: false,
|
||||
inlineRequires: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
resolver: {
|
||||
alias: {
|
||||
'@': './src',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = mergeConfig(defaultConfig, config);
|
||||
@@ -1,64 +0,0 @@
|
||||
{
|
||||
"name": "trackeep-mobile",
|
||||
"version": "1.0.0",
|
||||
"description": "Trackeep mobile app for productivity and knowledge management",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"android": "react-native run-android",
|
||||
"ios": "react-native run-ios",
|
||||
"start": "react-native start",
|
||||
"test": "jest",
|
||||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
||||
"build:android": "cd android && ./gradlew assembleRelease",
|
||||
"build:ios": "react-native run-ios --configuration Release"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-native-async-storage/async-storage": "^1.19.5",
|
||||
"@react-native-community/netinfo": "^11.4.1",
|
||||
"@react-navigation/bottom-tabs": "^6.5.11",
|
||||
"@react-navigation/drawer": "^6.6.6",
|
||||
"@react-navigation/native": "^6.1.9",
|
||||
"@react-navigation/native-stack": "^6.9.26",
|
||||
"@react-navigation/stack": "^6.3.20",
|
||||
"@types/react-native-push-notification": "^8.1.4",
|
||||
"@types/react-native-vector-icons": "^6.4.18",
|
||||
"axios": "^1.6.2",
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.72.6",
|
||||
"react-native-background-timer": "^2.4.1",
|
||||
"react-native-camera": "^4.2.1",
|
||||
"react-native-gesture-handler": "^2.13.4",
|
||||
"react-native-keychain": "^8.1.3",
|
||||
"react-native-paper": "^5.11.1",
|
||||
"react-native-permissions": "^3.10.1",
|
||||
"react-native-push-notification": "^8.1.1",
|
||||
"react-native-reanimated": "^3.5.4",
|
||||
"react-native-safe-area-context": "^4.7.4",
|
||||
"react-native-screens": "^3.25.0",
|
||||
"react-native-sqlite-storage": "^6.0.1",
|
||||
"react-native-svg": "^13.14.0",
|
||||
"react-native-vector-icons": "^10.0.2",
|
||||
"react-native-vision-camera": "^3.3.5",
|
||||
"react-native-voice": "^0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
"@babel/preset-env": "^7.20.0",
|
||||
"@babel/runtime": "^7.20.0",
|
||||
"@react-native/eslint-config": "^0.72.2",
|
||||
"@react-native/metro-config": "^0.72.11",
|
||||
"@tsconfig/react-native": "^3.0.0",
|
||||
"@types/react": "^18.0.24",
|
||||
"@types/react-test-renderer": "^18.0.0",
|
||||
"babel-jest": "^29.2.1",
|
||||
"eslint": "^8.19.0",
|
||||
"jest": "^29.2.1",
|
||||
"metro-react-native-babel-preset": "0.76.8",
|
||||
"prettier": "^2.4.1",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"typescript": "4.8.4"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "react-native"
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
NavigationContainer,
|
||||
DefaultTheme as NavigationDefaultTheme,
|
||||
DarkTheme as NavigationDarkTheme,
|
||||
} from '@react-navigation/native';
|
||||
import {
|
||||
Provider as PaperProvider,
|
||||
DefaultTheme as PaperDefaultTheme,
|
||||
MD3DarkTheme as PaperDarkTheme,
|
||||
} from 'react-native-paper';
|
||||
import { StatusBar } from 'react-native';
|
||||
import { AuthProvider } from './services/AuthContext';
|
||||
import { OfflineProvider } from './services/OfflineContext';
|
||||
import { NotificationProvider } from './services/NotificationContext';
|
||||
import { CameraProvider } from './services/CameraContext';
|
||||
import { VoiceProvider } from './services/VoiceContext';
|
||||
import { ServerConfigProvider } from './services/ServerConfigContext';
|
||||
import { RealtimeSyncProvider } from './services/RealtimeSyncContext';
|
||||
import AppNavigator from './navigation/AppNavigator';
|
||||
import { loadTheme } from './utils/storage';
|
||||
|
||||
const CombinedDefaultTheme = {
|
||||
...NavigationDefaultTheme,
|
||||
...PaperDefaultTheme,
|
||||
colors: {
|
||||
...NavigationDefaultTheme.colors,
|
||||
...PaperDefaultTheme.colors,
|
||||
},
|
||||
};
|
||||
|
||||
const CombinedDarkTheme = {
|
||||
...NavigationDarkTheme,
|
||||
...PaperDarkTheme,
|
||||
colors: {
|
||||
...NavigationDarkTheme.colors,
|
||||
...PaperDarkTheme.colors,
|
||||
},
|
||||
};
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [isDarkTheme, setIsDarkTheme] = useState(false);
|
||||
const [isThemeLoaded, setIsThemeLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const initializeTheme = async () => {
|
||||
try {
|
||||
const savedTheme = await loadTheme();
|
||||
setIsDarkTheme(savedTheme === 'dark');
|
||||
} catch (error) {
|
||||
console.error('Error loading theme:', error);
|
||||
} finally {
|
||||
setIsThemeLoaded(true);
|
||||
}
|
||||
};
|
||||
|
||||
initializeTheme();
|
||||
}, []);
|
||||
|
||||
const theme = isDarkTheme ? CombinedDarkTheme : CombinedDefaultTheme;
|
||||
|
||||
if (!isThemeLoaded) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<PaperProvider theme={theme}>
|
||||
<NavigationContainer theme={theme}>
|
||||
<StatusBar
|
||||
barStyle={isDarkTheme ? 'light-content' : 'dark-content'}
|
||||
backgroundColor={theme.colors.background}
|
||||
/>
|
||||
<ServerConfigProvider>
|
||||
<RealtimeSyncProvider>
|
||||
<AuthProvider>
|
||||
<NotificationProvider>
|
||||
<CameraProvider>
|
||||
<VoiceProvider>
|
||||
<OfflineProvider>
|
||||
<AppNavigator />
|
||||
</OfflineProvider>
|
||||
</VoiceProvider>
|
||||
</CameraProvider>
|
||||
</NotificationProvider>
|
||||
</AuthProvider>
|
||||
</RealtimeSyncProvider>
|
||||
</ServerConfigProvider>
|
||||
</NavigationContainer>
|
||||
</PaperProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
@@ -1,40 +0,0 @@
|
||||
import React from 'react';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import { useAuth } from '../services/AuthContext';
|
||||
import { useServerConfig } from '../services/ServerConfigContext';
|
||||
import AuthNavigator from './AuthNavigator';
|
||||
import TabNavigator from './TabNavigator';
|
||||
import LoadingScreen from '../screens/LoadingScreen';
|
||||
import ServerSetupScreen from '../screens/ServerSetupScreen';
|
||||
|
||||
export type RootStackParamList = {
|
||||
Auth: undefined;
|
||||
Main: undefined;
|
||||
Loading: undefined;
|
||||
ServerSetup: undefined;
|
||||
};
|
||||
|
||||
const Stack = createNativeStackNavigator<RootStackParamList>();
|
||||
|
||||
const AppNavigator: React.FC = () => {
|
||||
const { isAuthenticated, isLoading } = useAuth();
|
||||
const { isConfigured, isLoading: configLoading } = useServerConfig();
|
||||
|
||||
if (isLoading || configLoading) {
|
||||
return <LoadingScreen />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack.Navigator screenOptions={{ headerShown: false }}>
|
||||
{!isConfigured ? (
|
||||
<Stack.Screen name="ServerSetup" component={ServerSetupScreen} />
|
||||
) : isAuthenticated ? (
|
||||
<Stack.Screen name="Main" component={TabNavigator} />
|
||||
) : (
|
||||
<Stack.Screen name="Auth" component={AuthNavigator} />
|
||||
)}
|
||||
</Stack.Navigator>
|
||||
);
|
||||
};
|
||||
|
||||
export default AppNavigator;
|
||||
@@ -1,27 +0,0 @@
|
||||
import React from 'react';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import LoginScreen from '../screens/auth/LoginScreen';
|
||||
import RegisterScreen from '../screens/auth/RegisterScreen';
|
||||
|
||||
export type AuthStackParamList = {
|
||||
Login: undefined;
|
||||
Register: undefined;
|
||||
};
|
||||
|
||||
const Stack = createNativeStackNavigator<AuthStackParamList>();
|
||||
|
||||
const AuthNavigator: React.FC = () => {
|
||||
return (
|
||||
<Stack.Navigator
|
||||
screenOptions={{
|
||||
headerShown: false,
|
||||
gestureEnabled: false,
|
||||
}}
|
||||
>
|
||||
<Stack.Screen name="Login" component={LoginScreen} />
|
||||
<Stack.Screen name="Register" component={RegisterScreen} />
|
||||
</Stack.Navigator>
|
||||
);
|
||||
};
|
||||
|
||||
export default AuthNavigator;
|
||||
@@ -1,129 +0,0 @@
|
||||
import React from 'react';
|
||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import { useOffline } from '../services/OfflineContext';
|
||||
import { useTheme } from 'react-native-paper';
|
||||
|
||||
import DashboardScreen from '../screens/DashboardScreen';
|
||||
import BookmarksScreen from '../screens/BookmarksScreen';
|
||||
import TasksScreen from '../screens/TasksScreen';
|
||||
import NotesScreen from '../screens/NotesScreen';
|
||||
import TimeTrackingScreen from '../screens/TimeTrackingScreen';
|
||||
import SearchScreen from '../screens/SearchScreen';
|
||||
import SettingsScreen from '../screens/SettingsScreen';
|
||||
import AIAssistantScreen from '../screens/AIAssistantScreen';
|
||||
|
||||
export type MainTabParamList = {
|
||||
Dashboard: undefined;
|
||||
Bookmarks: undefined;
|
||||
Tasks: undefined;
|
||||
Notes: undefined;
|
||||
TimeTracking: undefined;
|
||||
Search: undefined;
|
||||
AIAssistant: undefined;
|
||||
Settings: undefined;
|
||||
};
|
||||
|
||||
const Tab = createBottomTabNavigator<MainTabParamList>();
|
||||
|
||||
const TabNavigator: React.FC = () => {
|
||||
const { pendingChanges } = useOffline();
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Tab.Navigator
|
||||
screenOptions={({ route }) => ({
|
||||
tabBarIcon: ({ color, size }) => {
|
||||
let iconName: string;
|
||||
|
||||
switch (route.name) {
|
||||
case 'Dashboard':
|
||||
iconName = 'view-dashboard';
|
||||
break;
|
||||
case 'Bookmarks':
|
||||
iconName = 'bookmark';
|
||||
break;
|
||||
case 'Tasks':
|
||||
iconName = 'check-circle';
|
||||
break;
|
||||
case 'Notes':
|
||||
iconName = 'note-text';
|
||||
break;
|
||||
case 'TimeTracking':
|
||||
iconName = 'timer';
|
||||
break;
|
||||
case 'Search':
|
||||
iconName = 'magnify';
|
||||
break;
|
||||
case 'AIAssistant':
|
||||
iconName = 'robot';
|
||||
break;
|
||||
case 'Settings':
|
||||
iconName = 'cog';
|
||||
break;
|
||||
default:
|
||||
iconName = 'help-circle';
|
||||
}
|
||||
|
||||
return <Icon name={iconName} size={size} color={color} />;
|
||||
},
|
||||
tabBarActiveTintColor: theme.colors.primary,
|
||||
tabBarInactiveTintColor: 'gray',
|
||||
tabBarStyle: {
|
||||
backgroundColor: theme.colors.surface,
|
||||
borderTopColor: theme.colors.outline,
|
||||
},
|
||||
headerStyle: {
|
||||
backgroundColor: theme.colors.surface,
|
||||
},
|
||||
headerTintColor: theme.colors.onSurface,
|
||||
})}
|
||||
>
|
||||
<Tab.Screen
|
||||
name="Dashboard"
|
||||
component={DashboardScreen}
|
||||
options={{
|
||||
title: 'Dashboard',
|
||||
tabBarBadge: pendingChanges > 0 ? pendingChanges : undefined,
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="Bookmarks"
|
||||
component={BookmarksScreen}
|
||||
options={{ title: 'Bookmarks' }}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="Tasks"
|
||||
component={TasksScreen}
|
||||
options={{ title: 'Tasks' }}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="Notes"
|
||||
component={NotesScreen}
|
||||
options={{ title: 'Notes' }}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="TimeTracking"
|
||||
component={TimeTrackingScreen}
|
||||
options={{ title: 'Time' }}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="Search"
|
||||
component={SearchScreen}
|
||||
options={{ title: 'Search' }}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="AIAssistant"
|
||||
component={AIAssistantScreen}
|
||||
options={{ title: 'AI' }}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="Settings"
|
||||
component={SettingsScreen}
|
||||
options={{ title: 'Settings' }}
|
||||
/>
|
||||
</Tab.Navigator>
|
||||
);
|
||||
};
|
||||
|
||||
export default TabNavigator;
|
||||
@@ -1,400 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
View,
|
||||
StyleSheet,
|
||||
ScrollView,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import {
|
||||
Text,
|
||||
Title,
|
||||
Paragraph,
|
||||
TextInput,
|
||||
Button,
|
||||
Avatar,
|
||||
Chip,
|
||||
} from 'react-native-paper';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { useRealtimeUpdates } from '../services/RealtimeSyncContext';
|
||||
import { useServerConfig } from '../services/ServerConfigContext';
|
||||
|
||||
interface Message {
|
||||
id: string;
|
||||
text: string;
|
||||
sender: 'user' | 'ai';
|
||||
timestamp: Date;
|
||||
type?: 'text' | 'recommendation' | 'analysis';
|
||||
}
|
||||
|
||||
const AIAssistantScreen: React.FC = () => {
|
||||
const [messages, setMessages] = useState<Message[]>([]);
|
||||
const [inputText, setInputText] = useState('');
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { config } = useServerConfig();
|
||||
|
||||
const [suggestions] = useState([
|
||||
'Help me organize my tasks',
|
||||
'Suggest bookmarks for learning React',
|
||||
'Analyze my productivity patterns',
|
||||
'Create a study plan',
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
// Initialize with welcome message
|
||||
setMessages([
|
||||
{
|
||||
id: '1',
|
||||
text: "Hello! I'm your AI assistant. I can help you organize tasks, suggest bookmarks, analyze your productivity, and much more. How can I assist you today?",
|
||||
sender: 'ai',
|
||||
timestamp: new Date(),
|
||||
type: 'text',
|
||||
},
|
||||
]);
|
||||
}, []);
|
||||
|
||||
// Listen for real-time AI updates
|
||||
useRealtimeUpdates((data) => {
|
||||
if (data.type === 'ai_response') {
|
||||
const newMessage: Message = {
|
||||
id: Date.now().toString(),
|
||||
text: data.response,
|
||||
sender: 'ai',
|
||||
timestamp: new Date(),
|
||||
type: data.responseType,
|
||||
};
|
||||
setMessages(prev => [...prev, newMessage]);
|
||||
setIsLoading(false);
|
||||
}
|
||||
});
|
||||
|
||||
const handleSendMessage = async () => {
|
||||
if (!inputText.trim()) return;
|
||||
|
||||
const userMessage: Message = {
|
||||
id: Date.now().toString(),
|
||||
text: inputText,
|
||||
sender: 'user',
|
||||
timestamp: new Date(),
|
||||
};
|
||||
|
||||
setMessages(prev => [...prev, userMessage]);
|
||||
setInputText('');
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
// Call LongCat AI API
|
||||
const response = await fetch(`${config?.baseUrl}/api/ai/chat`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${await getAuthToken()}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
message: inputText,
|
||||
context: 'trackeep_assistant',
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
const aiResponse: Message = {
|
||||
id: (Date.now() + 1).toString(),
|
||||
text: data.response,
|
||||
sender: 'ai',
|
||||
timestamp: new Date(),
|
||||
type: data.type || 'text',
|
||||
};
|
||||
setMessages(prev => [...prev, aiResponse]);
|
||||
} else {
|
||||
// Fallback to mock response
|
||||
const mockResponse: Message = {
|
||||
id: (Date.now() + 1).toString(),
|
||||
text: generateMockResponse(inputText),
|
||||
sender: 'ai',
|
||||
timestamp: new Date(),
|
||||
type: 'text',
|
||||
};
|
||||
setMessages(prev => [...prev, mockResponse]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error calling AI API:', error);
|
||||
// Fallback to mock response
|
||||
const mockResponse: Message = {
|
||||
id: (Date.now() + 1).toString(),
|
||||
text: generateMockResponse(inputText),
|
||||
sender: 'ai',
|
||||
timestamp: new Date(),
|
||||
type: 'text',
|
||||
};
|
||||
setMessages(prev => [...prev, mockResponse]);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const getAuthToken = async (): Promise<string | null> => {
|
||||
try {
|
||||
const authData = await AsyncStorage.getItem('trackeep_auth_token');
|
||||
return authData;
|
||||
} catch (error) {
|
||||
console.error('Error getting auth token:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const generateMockResponse = (userInput: string): string => {
|
||||
const input = userInput.toLowerCase();
|
||||
|
||||
if (input.includes('task') || input.includes('organize')) {
|
||||
return "I can help you organize your tasks! Based on your current tasks, I suggest prioritizing the high-priority items first. Would you like me to create a schedule for you?";
|
||||
} else if (input.includes('bookmark') || input.includes('learn')) {
|
||||
return "Great! I can suggest relevant bookmarks for your learning goals. I see you're interested in React - here are some top resources I recommend...";
|
||||
} else if (input.includes('productivity') || input.includes('analyze')) {
|
||||
return "Looking at your activity patterns, you're most productive in the morning. I suggest scheduling important tasks between 9-11 AM for better results.";
|
||||
} else if (input.includes('study') || input.includes('plan')) {
|
||||
return "I can create a personalized study plan for you! Based on your current notes and bookmarks, here's a structured learning path...";
|
||||
} else {
|
||||
return "I understand you need help with that. Let me analyze your current data and provide you with personalized recommendations.";
|
||||
}
|
||||
};
|
||||
|
||||
const handleSuggestionPress = (suggestion: string) => {
|
||||
setInputText(suggestion);
|
||||
};
|
||||
|
||||
const formatTime = (date: Date): string => {
|
||||
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||
};
|
||||
|
||||
const renderMessage = (message: Message) => (
|
||||
<View key={message.id} style={[
|
||||
styles.messageContainer,
|
||||
message.sender === 'user' ? styles.userMessage : styles.aiMessage,
|
||||
]}>
|
||||
{message.sender === 'ai' && (
|
||||
<Avatar.Text
|
||||
size={32}
|
||||
label="AI"
|
||||
style={styles.avatar}
|
||||
/>
|
||||
)}
|
||||
<View style={[
|
||||
styles.messageBubble,
|
||||
message.sender === 'user' ? styles.userBubble : styles.aiBubble,
|
||||
]}>
|
||||
<Text style={[
|
||||
styles.messageText,
|
||||
message.sender === 'user' ? styles.userText : styles.aiText,
|
||||
]}>
|
||||
{message.text}
|
||||
</Text>
|
||||
<Text style={styles.timestamp}>
|
||||
{formatTime(message.timestamp)}
|
||||
</Text>
|
||||
</View>
|
||||
{message.sender === 'user' && (
|
||||
<Avatar.Text
|
||||
size={32}
|
||||
label="U"
|
||||
style={styles.avatar}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
||||
style={styles.container}
|
||||
>
|
||||
<View style={styles.header}>
|
||||
<Title style={styles.title}>AI Assistant</Title>
|
||||
<Paragraph style={styles.subtitle}>
|
||||
Your personal productivity companion
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
<ScrollView
|
||||
style={styles.messagesContainer}
|
||||
contentContainerStyle={styles.messagesContent}
|
||||
>
|
||||
{messages.map(renderMessage)}
|
||||
|
||||
{isLoading && (
|
||||
<View style={[styles.messageContainer, styles.aiMessage]}>
|
||||
<Avatar.Text
|
||||
size={32}
|
||||
label="AI"
|
||||
style={styles.avatar}
|
||||
/>
|
||||
<View style={[styles.messageBubble, styles.aiBubble]}>
|
||||
<Text style={styles.aiText}>Thinking...</Text>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
|
||||
{/* Suggestions */}
|
||||
{messages.length === 1 && (
|
||||
<View style={styles.suggestionsContainer}>
|
||||
<Text style={styles.suggestionsTitle}>Try asking:</Text>
|
||||
<View style={styles.suggestionsList}>
|
||||
{suggestions.map((suggestion, index) => (
|
||||
<Chip
|
||||
key={index}
|
||||
onPress={() => handleSuggestionPress(suggestion)}
|
||||
style={styles.suggestionChip}
|
||||
textStyle={styles.suggestionText}
|
||||
>
|
||||
{suggestion}
|
||||
</Chip>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* Input Area */}
|
||||
<View style={styles.inputContainer}>
|
||||
<TextInput
|
||||
value={inputText}
|
||||
onChangeText={setInputText}
|
||||
placeholder="Ask me anything..."
|
||||
multiline
|
||||
maxLength={500}
|
||||
style={styles.textInput}
|
||||
right={
|
||||
<TextInput.Icon
|
||||
icon="send"
|
||||
onPress={handleSendMessage}
|
||||
disabled={!inputText.trim() || isLoading}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
mode="contained"
|
||||
onPress={handleSendMessage}
|
||||
disabled={!inputText.trim() || isLoading}
|
||||
loading={isLoading}
|
||||
style={styles.sendButton}
|
||||
>
|
||||
Send
|
||||
</Button>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
header: {
|
||||
padding: 16,
|
||||
backgroundColor: '#fff',
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#e0e0e0',
|
||||
},
|
||||
title: {
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
color: '#6200ee',
|
||||
},
|
||||
subtitle: {
|
||||
color: '#666',
|
||||
marginTop: 4,
|
||||
},
|
||||
messagesContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
messagesContent: {
|
||||
padding: 16,
|
||||
},
|
||||
messageContainer: {
|
||||
flexDirection: 'row',
|
||||
marginBottom: 16,
|
||||
alignItems: 'flex-end',
|
||||
},
|
||||
userMessage: {
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
aiMessage: {
|
||||
justifyContent: 'flex-start',
|
||||
},
|
||||
avatar: {
|
||||
marginHorizontal: 8,
|
||||
backgroundColor: '#6200ee',
|
||||
},
|
||||
messageBubble: {
|
||||
maxWidth: '70%',
|
||||
padding: 12,
|
||||
borderRadius: 16,
|
||||
minHeight: 40,
|
||||
},
|
||||
userBubble: {
|
||||
backgroundColor: '#6200ee',
|
||||
borderBottomRightRadius: 4,
|
||||
},
|
||||
aiBubble: {
|
||||
backgroundColor: '#fff',
|
||||
borderBottomLeftRadius: 4,
|
||||
borderWidth: 1,
|
||||
borderColor: '#e0e0e0',
|
||||
},
|
||||
messageText: {
|
||||
fontSize: 16,
|
||||
lineHeight: 20,
|
||||
},
|
||||
userText: {
|
||||
color: '#fff',
|
||||
},
|
||||
aiText: {
|
||||
color: '#333',
|
||||
},
|
||||
timestamp: {
|
||||
fontSize: 11,
|
||||
color: '#999',
|
||||
marginTop: 4,
|
||||
alignSelf: 'flex-end',
|
||||
},
|
||||
suggestionsContainer: {
|
||||
padding: 16,
|
||||
backgroundColor: '#fff',
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: '#e0e0e0',
|
||||
},
|
||||
suggestionsTitle: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
color: '#666',
|
||||
marginBottom: 8,
|
||||
},
|
||||
suggestionsList: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: 8,
|
||||
},
|
||||
suggestionChip: {
|
||||
backgroundColor: '#f0f0f0',
|
||||
},
|
||||
suggestionText: {
|
||||
fontSize: 12,
|
||||
color: '#333',
|
||||
},
|
||||
inputContainer: {
|
||||
padding: 16,
|
||||
backgroundColor: '#fff',
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: '#e0e0e0',
|
||||
},
|
||||
textInput: {
|
||||
marginBottom: 8,
|
||||
backgroundColor: '#f8f8f8',
|
||||
},
|
||||
sendButton: {
|
||||
backgroundColor: '#6200ee',
|
||||
},
|
||||
});
|
||||
|
||||
export default AIAssistantScreen;
|
||||
@@ -1,119 +0,0 @@
|
||||
import React from 'react';
|
||||
import { View, StyleSheet, FlatList } from 'react-native';
|
||||
import { Text, Card, Title, Paragraph, FAB, Searchbar } from 'react-native-paper';
|
||||
|
||||
const BookmarksScreen: React.FC = () => {
|
||||
const [searchQuery, setSearchQuery] = React.useState('');
|
||||
const [bookmarks] = React.useState([
|
||||
{
|
||||
id: '1',
|
||||
title: 'React Native Documentation',
|
||||
url: 'https://reactnative.dev',
|
||||
description: 'Official React Native documentation',
|
||||
tags: ['react', 'mobile', 'documentation'],
|
||||
isFavorite: true,
|
||||
createdAt: new Date(),
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'TypeScript Handbook',
|
||||
url: 'https://www.typescriptlang.org/docs',
|
||||
description: 'Learn TypeScript from the official handbook',
|
||||
tags: ['typescript', 'programming', 'tutorial'],
|
||||
isFavorite: false,
|
||||
createdAt: new Date(),
|
||||
},
|
||||
]);
|
||||
|
||||
const onChangeSearch = (query: string) => setSearchQuery(query);
|
||||
|
||||
const renderBookmark = ({ item }: any) => (
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title numberOfLines={1}>{item.title}</Title>
|
||||
<Paragraph numberOfLines={2}>{item.description}</Paragraph>
|
||||
<Text style={styles.url}>{item.url}</Text>
|
||||
<View style={styles.tagsContainer}>
|
||||
{item.tags.map((tag: string, index: number) => (
|
||||
<Text key={index} style={styles.tag}>
|
||||
#{tag}
|
||||
</Text>
|
||||
))}
|
||||
</View>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Searchbar
|
||||
placeholder="Search bookmarks..."
|
||||
onChangeText={onChangeSearch}
|
||||
value={searchQuery}
|
||||
style={styles.searchBar}
|
||||
/>
|
||||
|
||||
<FlatList
|
||||
data={bookmarks}
|
||||
renderItem={renderBookmark}
|
||||
keyExtractor={(item) => item.id}
|
||||
contentContainerStyle={styles.list}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>
|
||||
|
||||
<FAB
|
||||
icon="bookmark-plus"
|
||||
style={styles.fab}
|
||||
onPress={() => console.log('Add bookmark')}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
searchBar: {
|
||||
margin: 16,
|
||||
marginBottom: 8,
|
||||
},
|
||||
list: {
|
||||
paddingHorizontal: 16,
|
||||
paddingBottom: 80,
|
||||
},
|
||||
card: {
|
||||
marginBottom: 12,
|
||||
elevation: 2,
|
||||
},
|
||||
url: {
|
||||
color: '#6200ee',
|
||||
fontSize: 12,
|
||||
marginTop: 8,
|
||||
},
|
||||
tagsContainer: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
marginTop: 8,
|
||||
},
|
||||
tag: {
|
||||
backgroundColor: '#e3f2fd',
|
||||
color: '#1976d2',
|
||||
paddingHorizontal: 8,
|
||||
paddingVertical: 4,
|
||||
borderRadius: 12,
|
||||
fontSize: 10,
|
||||
marginRight: 4,
|
||||
marginBottom: 4,
|
||||
},
|
||||
fab: {
|
||||
position: 'absolute',
|
||||
margin: 16,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: '#6200ee',
|
||||
},
|
||||
});
|
||||
|
||||
export default BookmarksScreen;
|
||||
@@ -1,444 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { View, StyleSheet, ScrollView, RefreshControl, Dimensions } from 'react-native';
|
||||
import { Text, Card, Title, Paragraph, Button, FAB, Avatar, Chip, ProgressBar } from 'react-native-paper';
|
||||
import { useAuth } from '../services/AuthContext';
|
||||
import { useOffline } from '../services/OfflineContext';
|
||||
import { useRealtimeSync, useRealtimeUpdates } from '../services/RealtimeSyncContext';
|
||||
import { bookmarksAPI, tasksAPI, notesAPI } from '../services/api';
|
||||
|
||||
interface QuickStats {
|
||||
totalBookmarks: number;
|
||||
totalTasks: number;
|
||||
totalNotes: number;
|
||||
completedTasks: number;
|
||||
recentActivity: number;
|
||||
}
|
||||
|
||||
interface RecentActivity {
|
||||
id: string;
|
||||
type: 'bookmark' | 'task' | 'note';
|
||||
action: string;
|
||||
title: string;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
|
||||
const DashboardScreen: React.FC = () => {
|
||||
const { user } = useAuth();
|
||||
const { isOnline, pendingChanges, syncNow } = useOffline();
|
||||
const { isSyncing, lastSyncTime } = useRealtimeSync();
|
||||
|
||||
const [stats, setStats] = useState<QuickStats>({
|
||||
totalBookmarks: 0,
|
||||
totalTasks: 0,
|
||||
totalNotes: 0,
|
||||
completedTasks: 0,
|
||||
recentActivity: 0,
|
||||
});
|
||||
|
||||
const [recentActivity, setRecentActivity] = useState<RecentActivity[]>([]);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
loadDashboardData();
|
||||
}, []);
|
||||
|
||||
// Listen for real-time updates
|
||||
useRealtimeUpdates((data) => {
|
||||
console.log('Dashboard received real-time update:', data);
|
||||
loadDashboardData();
|
||||
});
|
||||
|
||||
const loadDashboardData = async () => {
|
||||
try {
|
||||
const [bookmarksRes, tasksRes, notesRes] = await Promise.all([
|
||||
bookmarksAPI.getBookmarks(),
|
||||
tasksAPI.getTasks(),
|
||||
notesAPI.getNotes(),
|
||||
]);
|
||||
|
||||
if (bookmarksRes.success && tasksRes.success && notesRes.success) {
|
||||
const bookmarks = bookmarksRes.data || [];
|
||||
const tasks = tasksRes.data || [];
|
||||
const notes = notesRes.data || [];
|
||||
|
||||
const completedTasks = tasks.filter(task => (task as any).completed).length;
|
||||
|
||||
setStats({
|
||||
totalBookmarks: bookmarks.length,
|
||||
totalTasks: tasks.length,
|
||||
totalNotes: notes.length,
|
||||
completedTasks,
|
||||
recentActivity: 5, // Mock recent activity count
|
||||
});
|
||||
|
||||
// Generate mock recent activity
|
||||
const activity: RecentActivity[] = [
|
||||
{
|
||||
id: '1',
|
||||
type: 'bookmark',
|
||||
action: 'Added',
|
||||
title: bookmarks[0]?.title || 'New bookmark',
|
||||
timestamp: '2 hours ago',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
type: 'task',
|
||||
action: 'Completed',
|
||||
title: tasks[0]?.title || 'New task',
|
||||
timestamp: '3 hours ago',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
type: 'note',
|
||||
action: 'Created',
|
||||
title: notes[0]?.title || 'New note',
|
||||
timestamp: '5 hours ago',
|
||||
},
|
||||
];
|
||||
|
||||
setRecentActivity(activity);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading dashboard data:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const onRefresh = async () => {
|
||||
setRefreshing(true);
|
||||
await loadDashboardData();
|
||||
if (isOnline && pendingChanges > 0) {
|
||||
await syncNow();
|
||||
}
|
||||
setRefreshing(false);
|
||||
};
|
||||
|
||||
const getTaskCompletionPercentage = () => {
|
||||
if (stats.totalTasks === 0) return 0;
|
||||
return Math.round((stats.completedTasks / stats.totalTasks) * 100);
|
||||
};
|
||||
|
||||
const formatLastSync = () => {
|
||||
if (!lastSyncTime) return 'Never';
|
||||
const now = Date.now();
|
||||
const diff = now - lastSyncTime;
|
||||
const minutes = Math.floor(diff / 60000);
|
||||
|
||||
if (minutes < 1) return 'Just now';
|
||||
if (minutes < 60) return `${minutes}m ago`;
|
||||
const hours = Math.floor(minutes / 60);
|
||||
if (hours < 24) return `${hours}h ago`;
|
||||
return `${Math.floor(hours / 24)}d ago`;
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ScrollView
|
||||
style={styles.scrollView}
|
||||
showsVerticalScrollIndicator={false}
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
|
||||
}
|
||||
>
|
||||
{/* Header Section */}
|
||||
<View style={styles.header}>
|
||||
<View style={styles.userSection}>
|
||||
<Avatar.Text
|
||||
size={60}
|
||||
label={user?.name?.charAt(0).toUpperCase() || 'U'}
|
||||
style={styles.avatar}
|
||||
/>
|
||||
<View style={styles.userInfo}>
|
||||
<Title style={styles.welcomeText}>
|
||||
Welcome back, {user?.name || 'User'}!
|
||||
</Title>
|
||||
<Paragraph style={styles.subtitle}>
|
||||
{isOnline ? '🟢 Connected' : '🔴 Offline'} •
|
||||
{isSyncing ? ' Syncing...' : ` Last sync: ${formatLastSync()}`}
|
||||
</Paragraph>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Quick Stats Cards */}
|
||||
<View style={styles.statsGrid}>
|
||||
<Card style={[styles.statCard, { backgroundColor: '#e3f2fd' }]}>
|
||||
<Card.Content style={styles.statContent}>
|
||||
<Text style={[styles.statNumber, { color: '#1976d2' }]}>
|
||||
{stats.totalBookmarks}
|
||||
</Text>
|
||||
<Text style={styles.statLabel}>Bookmarks</Text>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
<Card style={[styles.statCard, { backgroundColor: '#e8f5e8' }]}>
|
||||
<Card.Content style={styles.statContent}>
|
||||
<Text style={[styles.statNumber, { color: '#388e3c' }]}>
|
||||
{stats.totalTasks}
|
||||
</Text>
|
||||
<Text style={styles.statLabel}>Tasks</Text>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
<Card style={[styles.statCard, { backgroundColor: '#fff3e0' }]}>
|
||||
<Card.Content style={styles.statContent}>
|
||||
<Text style={[styles.statNumber, { color: '#f57c00' }]}>
|
||||
{stats.totalNotes}
|
||||
</Text>
|
||||
<Text style={styles.statLabel}>Notes</Text>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
</View>
|
||||
|
||||
{/* Task Progress */}
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title style={styles.cardTitle}>Task Progress</Title>
|
||||
<View style={styles.progressContainer}>
|
||||
<Text style={styles.progressText}>
|
||||
{stats.completedTasks} of {stats.totalTasks} tasks completed
|
||||
</Text>
|
||||
<ProgressBar
|
||||
progress={getTaskCompletionPercentage() / 100}
|
||||
color="#4caf50"
|
||||
style={styles.progressBar}
|
||||
/>
|
||||
<Text style={styles.progressPercentage}>
|
||||
{getTaskCompletionPercentage()}%
|
||||
</Text>
|
||||
</View>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
{/* Recent Activity */}
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title style={styles.cardTitle}>Recent Activity</Title>
|
||||
{recentActivity.length > 0 ? (
|
||||
recentActivity.map((activity) => (
|
||||
<View key={activity.id} style={styles.activityItem}>
|
||||
<View style={styles.activityIcon}>
|
||||
<Text style={styles.activityEmoji}>
|
||||
{activity.type === 'bookmark' ? '🔖' :
|
||||
activity.type === 'task' ? '✅' : '📝'}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.activityContent}>
|
||||
<Text style={styles.activityTitle}>
|
||||
{activity.action} {activity.title}
|
||||
</Text>
|
||||
<Text style={styles.activityTime}>
|
||||
{activity.timestamp}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
))
|
||||
) : (
|
||||
<Paragraph style={styles.emptyText}>No recent activity</Paragraph>
|
||||
)}
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
{/* Sync Status */}
|
||||
{!isOnline && pendingChanges > 0 && (
|
||||
<Card style={[styles.card, styles.offlineCard]}>
|
||||
<Card.Content>
|
||||
<Title style={styles.cardTitle}>Offline Mode</Title>
|
||||
<Paragraph>
|
||||
You have {pendingChanges} changes pending sync
|
||||
</Paragraph>
|
||||
<Button
|
||||
mode="outlined"
|
||||
onPress={syncNow}
|
||||
style={styles.syncButton}
|
||||
disabled={!isOnline || isSyncing}
|
||||
loading={isSyncing}
|
||||
>
|
||||
{isSyncing ? 'Syncing...' : 'Sync Now'}
|
||||
</Button>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* Quick Actions */}
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title style={styles.cardTitle}>Quick Actions</Title>
|
||||
<View style={styles.quickActions}>
|
||||
<Chip
|
||||
icon="bookmark-plus"
|
||||
onPress={() => console.log('Add bookmark')}
|
||||
style={styles.actionChip}
|
||||
>
|
||||
Add Bookmark
|
||||
</Chip>
|
||||
<Chip
|
||||
icon="plus"
|
||||
onPress={() => console.log('Add task')}
|
||||
style={styles.actionChip}
|
||||
>
|
||||
Add Task
|
||||
</Chip>
|
||||
<Chip
|
||||
icon="note-plus"
|
||||
onPress={() => console.log('Add note')}
|
||||
style={styles.actionChip}
|
||||
>
|
||||
Add Note
|
||||
</Chip>
|
||||
</View>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
</ScrollView>
|
||||
|
||||
<FAB
|
||||
icon="plus"
|
||||
style={styles.fab}
|
||||
onPress={() => console.log('Add new item')}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
padding: 16,
|
||||
},
|
||||
header: {
|
||||
marginBottom: 24,
|
||||
},
|
||||
userSection: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginBottom: 16,
|
||||
},
|
||||
avatar: {
|
||||
marginRight: 16,
|
||||
backgroundColor: '#6200ee',
|
||||
},
|
||||
userInfo: {
|
||||
flex: 1,
|
||||
},
|
||||
welcomeText: {
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
subtitle: {
|
||||
color: '#666',
|
||||
marginTop: 4,
|
||||
fontSize: 14,
|
||||
},
|
||||
statsGrid: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 20,
|
||||
},
|
||||
statCard: {
|
||||
width: (width - 48) / 3,
|
||||
elevation: 2,
|
||||
},
|
||||
statContent: {
|
||||
alignItems: 'center',
|
||||
paddingVertical: 16,
|
||||
},
|
||||
statNumber: {
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
statLabel: {
|
||||
fontSize: 12,
|
||||
color: '#666',
|
||||
marginTop: 4,
|
||||
textAlign: 'center',
|
||||
},
|
||||
card: {
|
||||
marginBottom: 16,
|
||||
elevation: 2,
|
||||
},
|
||||
cardTitle: {
|
||||
fontSize: 18,
|
||||
marginBottom: 12,
|
||||
color: '#333',
|
||||
},
|
||||
progressContainer: {
|
||||
marginTop: 8,
|
||||
},
|
||||
progressText: {
|
||||
fontSize: 14,
|
||||
color: '#666',
|
||||
marginBottom: 8,
|
||||
},
|
||||
progressBar: {
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
marginBottom: 8,
|
||||
},
|
||||
progressPercentage: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#4caf50',
|
||||
textAlign: 'center',
|
||||
},
|
||||
activityItem: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 8,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#f0f0f0',
|
||||
},
|
||||
activityIcon: {
|
||||
marginRight: 12,
|
||||
},
|
||||
activityEmoji: {
|
||||
fontSize: 20,
|
||||
},
|
||||
activityContent: {
|
||||
flex: 1,
|
||||
},
|
||||
activityTitle: {
|
||||
fontSize: 14,
|
||||
fontWeight: '500',
|
||||
color: '#333',
|
||||
},
|
||||
activityTime: {
|
||||
fontSize: 12,
|
||||
color: '#666',
|
||||
marginTop: 2,
|
||||
},
|
||||
emptyText: {
|
||||
textAlign: 'center',
|
||||
color: '#666',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
offlineCard: {
|
||||
backgroundColor: '#fff3cd',
|
||||
borderColor: '#ffeaa7',
|
||||
borderWidth: 1,
|
||||
},
|
||||
syncButton: {
|
||||
marginTop: 12,
|
||||
},
|
||||
quickActions: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: 8,
|
||||
},
|
||||
actionChip: {
|
||||
marginBottom: 8,
|
||||
},
|
||||
fab: {
|
||||
position: 'absolute',
|
||||
margin: 16,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: '#6200ee',
|
||||
},
|
||||
});
|
||||
|
||||
export default DashboardScreen;
|
||||
@@ -1,28 +0,0 @@
|
||||
import React from 'react';
|
||||
import { View, StyleSheet } from 'react-native';
|
||||
import { ActivityIndicator, Text } from 'react-native-paper';
|
||||
|
||||
const LoadingScreen: React.FC = () => {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ActivityIndicator size="large" />
|
||||
<Text style={styles.text}>Loading Trackeep...</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
text: {
|
||||
marginTop: 16,
|
||||
fontSize: 16,
|
||||
color: '#666',
|
||||
},
|
||||
});
|
||||
|
||||
export default LoadingScreen;
|
||||
@@ -1,104 +0,0 @@
|
||||
import React from 'react';
|
||||
import { View, StyleSheet, FlatList } from 'react-native';
|
||||
import { Text, Card, Title, Paragraph, FAB } from 'react-native-paper';
|
||||
|
||||
const NotesScreen: React.FC = () => {
|
||||
const [notes] = React.useState([
|
||||
{
|
||||
id: '1',
|
||||
title: 'Mobile App Architecture',
|
||||
content: 'React Native with TypeScript, navigation, offline support...',
|
||||
tags: ['architecture', 'mobile', 'react-native'],
|
||||
createdAt: new Date(),
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Meeting Notes - Product Review',
|
||||
content: 'Discussed new features, timeline, and user feedback...',
|
||||
tags: ['meeting', 'product', 'review'],
|
||||
createdAt: new Date(),
|
||||
},
|
||||
]);
|
||||
|
||||
const renderNote = ({ item }: any) => (
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title numberOfLines={1}>{item.title}</Title>
|
||||
<Paragraph numberOfLines={3}>{item.content}</Paragraph>
|
||||
<View style={styles.tagsContainer}>
|
||||
{item.tags.map((tag: string, index: number) => (
|
||||
<Text key={index} style={styles.tag}>
|
||||
#{tag}
|
||||
</Text>
|
||||
))}
|
||||
</View>
|
||||
<Text style={styles.date}>
|
||||
{item.createdAt.toLocaleDateString()}
|
||||
</Text>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<FlatList
|
||||
data={notes}
|
||||
renderItem={renderNote}
|
||||
keyExtractor={(item) => item.id}
|
||||
contentContainerStyle={styles.list}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>
|
||||
|
||||
<FAB
|
||||
icon="plus"
|
||||
style={styles.fab}
|
||||
onPress={() => console.log('Add note')}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
list: {
|
||||
padding: 16,
|
||||
paddingBottom: 80,
|
||||
},
|
||||
card: {
|
||||
marginBottom: 12,
|
||||
elevation: 2,
|
||||
},
|
||||
tagsContainer: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
marginTop: 8,
|
||||
},
|
||||
tag: {
|
||||
backgroundColor: '#e8f5e8',
|
||||
color: '#2e7d32',
|
||||
paddingHorizontal: 8,
|
||||
paddingVertical: 4,
|
||||
borderRadius: 12,
|
||||
fontSize: 10,
|
||||
marginRight: 4,
|
||||
marginBottom: 4,
|
||||
},
|
||||
date: {
|
||||
fontSize: 10,
|
||||
color: '#666',
|
||||
marginTop: 8,
|
||||
textAlign: 'right',
|
||||
},
|
||||
fab: {
|
||||
position: 'absolute',
|
||||
margin: 16,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: '#6200ee',
|
||||
},
|
||||
});
|
||||
|
||||
export default NotesScreen;
|
||||
@@ -1,213 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import { View, StyleSheet, FlatList } from 'react-native';
|
||||
import { Text, Card, Title, Paragraph, Searchbar, Chip } from 'react-native-paper';
|
||||
|
||||
const SearchScreen: React.FC = () => {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [selectedFilter, setSelectedFilter] = useState('all');
|
||||
|
||||
const filters = [
|
||||
{ id: 'all', label: 'All' },
|
||||
{ id: 'bookmarks', label: 'Bookmarks' },
|
||||
{ id: 'tasks', label: 'Tasks' },
|
||||
{ id: 'notes', label: 'Notes' },
|
||||
];
|
||||
|
||||
const searchResults = [
|
||||
{
|
||||
id: '1',
|
||||
type: 'bookmark',
|
||||
title: 'React Native Documentation',
|
||||
description: 'Official React Native documentation and guides',
|
||||
url: 'https://reactnative.dev',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
type: 'task',
|
||||
title: 'Complete mobile app setup',
|
||||
description: 'Finish React Native project structure and navigation',
|
||||
status: 'in_progress',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
type: 'note',
|
||||
title: 'Mobile App Architecture',
|
||||
content: 'React Native with TypeScript, navigation patterns...',
|
||||
tags: ['architecture', 'mobile'],
|
||||
},
|
||||
];
|
||||
|
||||
const onChangeSearch = (query: string) => setSearchQuery(query);
|
||||
|
||||
const renderResult = ({ item }: any) => {
|
||||
const getTypeIcon = (type: string) => {
|
||||
switch (type) {
|
||||
case 'bookmark': return '🔖';
|
||||
case 'task': return '✅';
|
||||
case 'note': return '📝';
|
||||
default: return '📄';
|
||||
}
|
||||
};
|
||||
|
||||
const getTypeColor = (type: string) => {
|
||||
switch (type) {
|
||||
case 'bookmark': return '#1976d2';
|
||||
case 'task': return '#f44336';
|
||||
case 'note': return '#4caf50';
|
||||
default: return '#666';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Card style={styles.resultCard}>
|
||||
<Card.Content>
|
||||
<View style={styles.resultHeader}>
|
||||
<Text style={styles.typeIcon}>{getTypeIcon(item.type)}</Text>
|
||||
<Text style={[styles.typeLabel, { color: getTypeColor(item.type) }]}>
|
||||
{item.type.charAt(0).toUpperCase() + item.type.slice(1)}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<Title numberOfLines={1} style={styles.resultTitle}>
|
||||
{item.title}
|
||||
</Title>
|
||||
|
||||
<Paragraph numberOfLines={2} style={styles.resultDescription}>
|
||||
{item.description || item.content}
|
||||
</Paragraph>
|
||||
|
||||
{item.url && (
|
||||
<Text style={styles.resultUrl} numberOfLines={1}>
|
||||
{item.url}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{item.tags && (
|
||||
<View style={styles.tagsContainer}>
|
||||
{item.tags.map((tag: string, index: number) => (
|
||||
<Chip key={index} style={styles.tag}>
|
||||
{tag}
|
||||
</Chip>
|
||||
))}
|
||||
</View>
|
||||
)}
|
||||
</Card.Content>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Searchbar
|
||||
placeholder="Search everything..."
|
||||
onChangeText={onChangeSearch}
|
||||
value={searchQuery}
|
||||
style={styles.searchBar}
|
||||
/>
|
||||
|
||||
<View style={styles.filtersContainer}>
|
||||
{filters.map(filter => (
|
||||
<Chip
|
||||
key={filter.id}
|
||||
selected={selectedFilter === filter.id}
|
||||
onPress={() => setSelectedFilter(filter.id)}
|
||||
style={styles.filterChip}
|
||||
>
|
||||
{filter.label}
|
||||
</Chip>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<FlatList
|
||||
data={searchResults}
|
||||
renderItem={renderResult}
|
||||
keyExtractor={(item) => item.id}
|
||||
contentContainerStyle={styles.resultsList}
|
||||
showsVerticalScrollIndicator={false}
|
||||
ListEmptyComponent={
|
||||
<View style={styles.emptyContainer}>
|
||||
<Text style={styles.emptyText}>
|
||||
{searchQuery ? 'No results found' : 'Start typing to search'}
|
||||
</Text>
|
||||
</View>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
searchBar: {
|
||||
margin: 16,
|
||||
marginBottom: 8,
|
||||
},
|
||||
filtersContainer: {
|
||||
flexDirection: 'row',
|
||||
paddingHorizontal: 16,
|
||||
paddingBottom: 8,
|
||||
},
|
||||
filterChip: {
|
||||
marginRight: 8,
|
||||
},
|
||||
resultsList: {
|
||||
paddingHorizontal: 16,
|
||||
paddingBottom: 16,
|
||||
},
|
||||
resultCard: {
|
||||
marginBottom: 12,
|
||||
elevation: 2,
|
||||
},
|
||||
resultHeader: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginBottom: 8,
|
||||
},
|
||||
typeIcon: {
|
||||
fontSize: 16,
|
||||
marginRight: 8,
|
||||
},
|
||||
typeLabel: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
textTransform: 'uppercase',
|
||||
},
|
||||
resultTitle: {
|
||||
fontSize: 16,
|
||||
marginBottom: 4,
|
||||
},
|
||||
resultDescription: {
|
||||
fontSize: 14,
|
||||
color: '#666',
|
||||
marginBottom: 8,
|
||||
},
|
||||
resultUrl: {
|
||||
fontSize: 12,
|
||||
color: '#1976d2',
|
||||
marginBottom: 8,
|
||||
},
|
||||
tagsContainer: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
tag: {
|
||||
marginRight: 4,
|
||||
marginBottom: 4,
|
||||
},
|
||||
emptyContainer: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 60,
|
||||
},
|
||||
emptyText: {
|
||||
fontSize: 16,
|
||||
color: '#666',
|
||||
textAlign: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
export default SearchScreen;
|
||||
@@ -1,321 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
View,
|
||||
StyleSheet,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
Alert,
|
||||
} from 'react-native';
|
||||
import {
|
||||
Card,
|
||||
Title,
|
||||
Paragraph,
|
||||
TextInput,
|
||||
Button,
|
||||
HelperText,
|
||||
} from 'react-native-paper';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { useServerConfig } from '../services/ServerConfigContext';
|
||||
import { updateAPIBaseURL } from '../services/api';
|
||||
|
||||
interface ServerConfig {
|
||||
baseUrl: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
const ServerSetupScreen: React.FC = () => {
|
||||
const [config, setConfig] = useState<ServerConfig>({
|
||||
baseUrl: '',
|
||||
username: '',
|
||||
password: '',
|
||||
});
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [errors, setErrors] = useState<Partial<ServerConfig>>({});
|
||||
|
||||
const { setConfig: saveConfig } = useServerConfig();
|
||||
|
||||
const validateConfig = (): boolean => {
|
||||
const newErrors: Partial<ServerConfig> = {};
|
||||
|
||||
if (!config.baseUrl.trim()) {
|
||||
newErrors.baseUrl = 'Server URL is required';
|
||||
} else if (!isValidUrl(config.baseUrl)) {
|
||||
newErrors.baseUrl = 'Please enter a valid URL (e.g., https://your-server.com)';
|
||||
}
|
||||
|
||||
if (!config.username.trim()) {
|
||||
newErrors.username = 'Username is required';
|
||||
}
|
||||
|
||||
if (!config.password.trim()) {
|
||||
newErrors.password = 'Password is required';
|
||||
}
|
||||
|
||||
setErrors(newErrors);
|
||||
return Object.keys(newErrors).length === 0;
|
||||
};
|
||||
|
||||
const isValidUrl = (url: string): boolean => {
|
||||
try {
|
||||
const urlObj = new URL(url.startsWith('http') ? url : `https://${url}`);
|
||||
return urlObj.protocol === 'http:' || urlObj.protocol === 'https:';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const testConnection = async (): Promise<boolean> => {
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
||||
|
||||
const response = await fetch(`${config.baseUrl}/api/health`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
return response.ok;
|
||||
} catch (error) {
|
||||
console.error('Connection test failed:', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleTestConnection = async () => {
|
||||
if (!config.baseUrl.trim()) {
|
||||
Alert.alert('Error', 'Please enter a server URL first');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const isConnected = await testConnection();
|
||||
if (isConnected) {
|
||||
Alert.alert('Success', 'Connection to server successful!');
|
||||
} else {
|
||||
Alert.alert(
|
||||
'Connection Failed',
|
||||
'Could not connect to the server. Please check the URL and ensure the server is running.'
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
Alert.alert('Error', 'Failed to test connection. Please try again.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSetup = async () => {
|
||||
if (!validateConfig()) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const isConnected = await testConnection();
|
||||
if (!isConnected) {
|
||||
Alert.alert(
|
||||
'Connection Failed',
|
||||
'Could not connect to the server. Please check the URL and try again.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Test authentication
|
||||
const authResponse = await fetch(`${config.baseUrl}/api/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
username: config.username,
|
||||
password: config.password,
|
||||
}),
|
||||
});
|
||||
|
||||
if (authResponse.ok) {
|
||||
const authData = await authResponse.json();
|
||||
if (authData.token) {
|
||||
await saveConfig(config);
|
||||
updateAPIBaseURL(`${config.baseUrl}/api`);
|
||||
Alert.alert('Success', 'Server configuration completed successfully!');
|
||||
// Navigation will be handled automatically by the AppNavigator
|
||||
} else {
|
||||
Alert.alert('Authentication Failed', 'Invalid username or password.');
|
||||
}
|
||||
} else {
|
||||
Alert.alert('Authentication Failed', 'Invalid username or password.');
|
||||
}
|
||||
} catch (error) {
|
||||
Alert.alert('Setup Failed', 'An error occurred during setup. Please try again.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<KeyboardAvoidingView
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
||||
style={styles.keyboardAvoidingView}
|
||||
>
|
||||
<View style={styles.content}>
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title style={styles.title}>Welcome to Trackeep</Title>
|
||||
<Paragraph style={styles.subtitle}>
|
||||
Connect to your Trackeep server to get started
|
||||
</Paragraph>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title style={styles.cardTitle}>Server Configuration</Title>
|
||||
|
||||
<TextInput
|
||||
label="Server URL"
|
||||
value={config.baseUrl}
|
||||
onChangeText={(text) => setConfig({ ...config, baseUrl: text })}
|
||||
placeholder="https://your-server.com"
|
||||
autoCapitalize="none"
|
||||
keyboardType="url"
|
||||
style={styles.input}
|
||||
error={!!errors.baseUrl}
|
||||
/>
|
||||
<HelperText type="error" visible={!!errors.baseUrl}>
|
||||
{errors.baseUrl}
|
||||
</HelperText>
|
||||
|
||||
<TextInput
|
||||
label="Username"
|
||||
value={config.username}
|
||||
onChangeText={(text) => setConfig({ ...config, username: text })}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
style={styles.input}
|
||||
error={!!errors.username}
|
||||
/>
|
||||
<HelperText type="error" visible={!!errors.username}>
|
||||
{errors.username}
|
||||
</HelperText>
|
||||
|
||||
<TextInput
|
||||
label="Password"
|
||||
value={config.password}
|
||||
onChangeText={(text) => setConfig({ ...config, password: text })}
|
||||
secureTextEntry
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
style={styles.input}
|
||||
error={!!errors.password}
|
||||
/>
|
||||
<HelperText type="error" visible={!!errors.password}>
|
||||
{errors.password}
|
||||
</HelperText>
|
||||
|
||||
<Button
|
||||
mode="outlined"
|
||||
onPress={handleTestConnection}
|
||||
disabled={isLoading || !config.baseUrl.trim()}
|
||||
style={styles.testButton}
|
||||
loading={isLoading}
|
||||
>
|
||||
Test Connection
|
||||
</Button>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
<Card style={styles.infoCard}>
|
||||
<Card.Content>
|
||||
<Title style={styles.cardTitle}>Need Help?</Title>
|
||||
<Paragraph style={styles.infoText}>
|
||||
• Enter the full URL of your Trackeep server
|
||||
</Paragraph>
|
||||
<Paragraph style={styles.infoText}>
|
||||
• Use your existing Trackeep account credentials
|
||||
</Paragraph>
|
||||
<Paragraph style={styles.infoText}>
|
||||
• Make sure your server is accessible from this device
|
||||
</Paragraph>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
<Button
|
||||
mode="contained"
|
||||
onPress={handleSetup}
|
||||
disabled={isLoading}
|
||||
loading={isLoading}
|
||||
style={styles.setupButton}
|
||||
contentStyle={styles.setupButtonContent}
|
||||
>
|
||||
Complete Setup
|
||||
</Button>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
keyboardAvoidingView: {
|
||||
flex: 1,
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
padding: 16,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
card: {
|
||||
marginBottom: 16,
|
||||
elevation: 2,
|
||||
},
|
||||
infoCard: {
|
||||
marginBottom: 24,
|
||||
backgroundColor: '#e3f2fd',
|
||||
},
|
||||
title: {
|
||||
textAlign: 'center',
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
color: '#6200ee',
|
||||
},
|
||||
subtitle: {
|
||||
textAlign: 'center',
|
||||
marginTop: 8,
|
||||
color: '#666',
|
||||
},
|
||||
cardTitle: {
|
||||
fontSize: 18,
|
||||
marginBottom: 16,
|
||||
color: '#333',
|
||||
},
|
||||
input: {
|
||||
marginBottom: 8,
|
||||
},
|
||||
testButton: {
|
||||
marginTop: 8,
|
||||
},
|
||||
infoText: {
|
||||
fontSize: 14,
|
||||
color: '#666',
|
||||
marginBottom: 4,
|
||||
},
|
||||
setupButton: {
|
||||
backgroundColor: '#6200ee',
|
||||
},
|
||||
setupButtonContent: {
|
||||
paddingVertical: 8,
|
||||
},
|
||||
});
|
||||
|
||||
export default ServerSetupScreen;
|
||||
@@ -1,324 +0,0 @@
|
||||
import React from 'react';
|
||||
import { View, StyleSheet, ScrollView, Alert } from 'react-native';
|
||||
import { List, Switch, Text, Card, Title, Button } from 'react-native-paper';
|
||||
import { useAuth } from '../services/AuthContext';
|
||||
import { useOffline } from '../services/OfflineContext';
|
||||
import { useNotifications } from '../services/NotificationContext';
|
||||
import { useCamera } from '../services/CameraContext';
|
||||
import { useVoice } from '../services/VoiceContext';
|
||||
|
||||
const SettingsScreen: React.FC = () => {
|
||||
const { user, logout } = useAuth();
|
||||
const { isOnline, syncNow } = useOffline();
|
||||
const { hasPermission: hasNotificationPermission, requestPermission: requestNotificationPermission } = useNotifications();
|
||||
const { hasPermission: hasCameraPermission, requestPermission: requestCameraPermission, scanDocument } = useCamera();
|
||||
const { hasPermission: hasVoicePermission, requestPermission: requestVoicePermission, isRecording, startRecording, stopRecording } = useVoice();
|
||||
|
||||
const [notifications, setNotifications] = React.useState(true);
|
||||
const [darkMode, setDarkMode] = React.useState(false);
|
||||
const [autoSync, setAutoSync] = React.useState(true);
|
||||
|
||||
const handleLogout = async () => {
|
||||
await logout();
|
||||
};
|
||||
|
||||
const handleNotificationPermission = async () => {
|
||||
if (!hasNotificationPermission) {
|
||||
const granted = await requestNotificationPermission();
|
||||
if (granted) {
|
||||
Alert.alert('Success', 'Notification permission granted!');
|
||||
} else {
|
||||
Alert.alert('Permission Denied', 'Notification permission is required for reminders');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleCameraPermission = async () => {
|
||||
if (!hasCameraPermission) {
|
||||
const granted = await requestCameraPermission();
|
||||
if (granted) {
|
||||
Alert.alert('Success', 'Camera permission granted!');
|
||||
} else {
|
||||
Alert.alert('Permission Denied', 'Camera permission is required for document scanning');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleVoicePermission = async () => {
|
||||
if (!hasVoicePermission) {
|
||||
const granted = await requestVoicePermission();
|
||||
if (granted) {
|
||||
Alert.alert('Success', 'Microphone permission granted!');
|
||||
} else {
|
||||
Alert.alert('Permission Denied', 'Microphone permission is required for voice recording');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleTestNotification = () => {
|
||||
// This would use the notification service to show a test notification
|
||||
Alert.alert('Test Notification', 'This is a test notification!');
|
||||
};
|
||||
|
||||
const handleTestCamera = async () => {
|
||||
try {
|
||||
const result = await scanDocument();
|
||||
if (result) {
|
||||
Alert.alert('Success', 'Document scanned successfully!');
|
||||
}
|
||||
} catch (error) {
|
||||
Alert.alert('Error', 'Failed to scan document');
|
||||
}
|
||||
};
|
||||
|
||||
const handleTestVoice = async () => {
|
||||
if (isRecording) {
|
||||
const recording = await stopRecording();
|
||||
if (recording) {
|
||||
Alert.alert('Success', `Voice recorded! Duration: ${recording.duration}s`);
|
||||
}
|
||||
} else {
|
||||
startRecording();
|
||||
Alert.alert('Recording', 'Voice recording started...');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title>Account</Title>
|
||||
<Text style={styles.userInfo}>
|
||||
{user?.name} ({user?.email})
|
||||
</Text>
|
||||
<Button
|
||||
mode="outlined"
|
||||
onPress={handleLogout}
|
||||
style={styles.logoutButton}
|
||||
>
|
||||
Sign Out
|
||||
</Button>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title>Preferences</Title>
|
||||
|
||||
<List.Item
|
||||
title="Push Notifications"
|
||||
description="Receive notifications for tasks and reminders"
|
||||
right={() => (
|
||||
<Switch
|
||||
value={notifications}
|
||||
onValueChange={setNotifications}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<List.Item
|
||||
title="Dark Mode"
|
||||
description="Use dark theme"
|
||||
right={() => (
|
||||
<Switch
|
||||
value={darkMode}
|
||||
onValueChange={setDarkMode}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<List.Item
|
||||
title="Auto Sync"
|
||||
description="Automatically sync when online"
|
||||
right={() => (
|
||||
<Switch
|
||||
value={autoSync}
|
||||
onValueChange={setAutoSync}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title>📱 Mobile Features</Title>
|
||||
|
||||
<List.Item
|
||||
title="Push Notifications"
|
||||
description={hasNotificationPermission ? "Permission granted" : "Permission required"}
|
||||
left={() => <Text style={styles.featureIcon}>🔔</Text>}
|
||||
right={() => (
|
||||
<View style={styles.featureActions}>
|
||||
{!hasNotificationPermission && (
|
||||
<Button
|
||||
mode="outlined"
|
||||
onPress={handleNotificationPermission}
|
||||
compact
|
||||
>
|
||||
Enable
|
||||
</Button>
|
||||
)}
|
||||
{hasNotificationPermission && (
|
||||
<Button
|
||||
mode="text"
|
||||
onPress={handleTestNotification}
|
||||
compact
|
||||
>
|
||||
Test
|
||||
</Button>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
|
||||
<List.Item
|
||||
title="Camera & Document Scanning"
|
||||
description={hasCameraPermission ? "Permission granted" : "Permission required"}
|
||||
left={() => <Text style={styles.featureIcon}>📸</Text>}
|
||||
right={() => (
|
||||
<View style={styles.featureActions}>
|
||||
{!hasCameraPermission && (
|
||||
<Button
|
||||
mode="outlined"
|
||||
onPress={handleCameraPermission}
|
||||
compact
|
||||
>
|
||||
Enable
|
||||
</Button>
|
||||
)}
|
||||
{hasCameraPermission && (
|
||||
<Button
|
||||
mode="text"
|
||||
onPress={handleTestCamera}
|
||||
compact
|
||||
>
|
||||
Test
|
||||
</Button>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
|
||||
<List.Item
|
||||
title="Voice Recording"
|
||||
description={hasVoicePermission ? "Permission granted" : "Permission required"}
|
||||
left={() => <Text style={styles.featureIcon}>🎤</Text>}
|
||||
right={() => (
|
||||
<View style={styles.featureActions}>
|
||||
{!hasVoicePermission && (
|
||||
<Button
|
||||
mode="outlined"
|
||||
onPress={handleVoicePermission}
|
||||
compact
|
||||
>
|
||||
Enable
|
||||
</Button>
|
||||
)}
|
||||
{hasVoicePermission && (
|
||||
<Button
|
||||
mode={isRecording ? "contained" : "text"}
|
||||
onPress={handleTestVoice}
|
||||
compact
|
||||
>
|
||||
{isRecording ? "Stop" : "Test"}
|
||||
</Button>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title>Sync Status</Title>
|
||||
|
||||
<List.Item
|
||||
title="Connection"
|
||||
description={isOnline ? 'Connected' : 'Offline'}
|
||||
left={() => (
|
||||
<Text style={styles.statusIcon}>
|
||||
{isOnline ? '🟢' : '🔴'}
|
||||
</Text>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Button
|
||||
mode="outlined"
|
||||
onPress={syncNow}
|
||||
disabled={!isOnline}
|
||||
style={styles.syncButton}
|
||||
>
|
||||
Sync Now
|
||||
</Button>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<Title>About</Title>
|
||||
|
||||
<List.Item
|
||||
title="Version"
|
||||
description="1.0.0"
|
||||
/>
|
||||
|
||||
<List.Item
|
||||
title="Build"
|
||||
description="React Native Mobile App"
|
||||
/>
|
||||
|
||||
<List.Item
|
||||
title="GitHub"
|
||||
description="View source code"
|
||||
onPress={() => console.log('Open GitHub')}
|
||||
/>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
},
|
||||
card: {
|
||||
margin: 16,
|
||||
elevation: 2,
|
||||
},
|
||||
userInfo: {
|
||||
fontSize: 16,
|
||||
marginBottom: 16,
|
||||
color: '#666',
|
||||
},
|
||||
logoutButton: {
|
||||
marginTop: 8,
|
||||
},
|
||||
statusIcon: {
|
||||
fontSize: 16,
|
||||
width: 24,
|
||||
textAlign: 'center',
|
||||
},
|
||||
syncButton: {
|
||||
marginTop: 8,
|
||||
},
|
||||
featureIcon: {
|
||||
fontSize: 16,
|
||||
width: 24,
|
||||
textAlign: 'center',
|
||||
},
|
||||
featureActions: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
export default SettingsScreen;
|
||||
@@ -1,132 +0,0 @@
|
||||
import React from 'react';
|
||||
import { View, StyleSheet, FlatList } from 'react-native';
|
||||
import { Text, Card, Title, Paragraph, FAB, Checkbox } from 'react-native-paper';
|
||||
|
||||
const TasksScreen: React.FC = () => {
|
||||
const [tasks, setTasks] = React.useState([
|
||||
{
|
||||
id: '1',
|
||||
title: 'Complete mobile app setup',
|
||||
description: 'Finish React Native project structure',
|
||||
status: 'in_progress' as const,
|
||||
priority: 'high' as const,
|
||||
completed: false,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Review pull requests',
|
||||
description: 'Check and merge pending PRs',
|
||||
status: 'todo' as const,
|
||||
priority: 'medium' as const,
|
||||
completed: false,
|
||||
},
|
||||
]);
|
||||
|
||||
const toggleTask = (taskId: string) => {
|
||||
setTasks(prev =>
|
||||
prev.map(task =>
|
||||
task.id === taskId ? { ...task, completed: !task.completed } : task
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const getPriorityColor = (priority: string) => {
|
||||
switch (priority) {
|
||||
case 'high': return '#f44336';
|
||||
case 'medium': return '#ff9800';
|
||||
case 'low': return '#4caf50';
|
||||
default: return '#666';
|
||||
}
|
||||
};
|
||||
|
||||
const renderTask = ({ item }: any) => (
|
||||
<Card style={styles.card}>
|
||||
<Card.Content>
|
||||
<View style={styles.taskHeader}>
|
||||
<Checkbox
|
||||
status={item.completed ? 'checked' : 'unchecked'}
|
||||
onPress={() => toggleTask(item.id)}
|
||||
/>
|
||||
<View style={styles.taskContent}>
|
||||
<Title style={[styles.taskTitle, item.completed && styles.completedTitle]}>
|
||||
{item.title}
|
||||
</Title>
|
||||
<Paragraph style={styles.taskDescription}>
|
||||
{item.description}
|
||||
</Paragraph>
|
||||
<Text style={[styles.priority, { color: getPriorityColor(item.priority) }]}>
|
||||
{item.priority.toUpperCase()}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<FlatList
|
||||
data={tasks}
|
||||
renderItem={renderTask}
|
||||
keyExtractor={(item) => item.id}
|
||||
contentContainerStyle={styles.list}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>
|
||||
|
||||
<FAB
|
||||
icon="plus"
|
||||
style={styles.fab}
|
||||
onPress={() => console.log('Add task')}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
list: {
|
||||
padding: 16,
|
||||
paddingBottom: 80,
|
||||
},
|
||||
card: {
|
||||
marginBottom: 12,
|
||||
elevation: 2,
|
||||
},
|
||||
taskHeader: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
},
|
||||
taskContent: {
|
||||
flex: 1,
|
||||
marginLeft: 12,
|
||||
},
|
||||
taskTitle: {
|
||||
fontSize: 16,
|
||||
},
|
||||
completedTitle: {
|
||||
textDecorationLine: 'line-through',
|
||||
color: '#666',
|
||||
},
|
||||
taskDescription: {
|
||||
marginTop: 4,
|
||||
fontSize: 14,
|
||||
},
|
||||
priority: {
|
||||
fontSize: 10,
|
||||
fontWeight: 'bold',
|
||||
marginTop: 8,
|
||||
textTransform: 'uppercase',
|
||||
},
|
||||
fab: {
|
||||
position: 'absolute',
|
||||
margin: 16,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: '#6200ee',
|
||||
},
|
||||
});
|
||||
|
||||
export default TasksScreen;
|
||||
@@ -1,194 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { View, StyleSheet } from 'react-native';
|
||||
import { Text, Card, Title, Paragraph, Button, FAB } from 'react-native-paper';
|
||||
|
||||
const TimeTrackingScreen: React.FC = () => {
|
||||
const [isTimerRunning, setIsTimerRunning] = useState(false);
|
||||
const [elapsedTime, setElapsedTime] = useState(0);
|
||||
const [currentTask, setCurrentTask] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
let interval: NodeJS.Timeout;
|
||||
if (isTimerRunning) {
|
||||
interval = setInterval(() => {
|
||||
setElapsedTime(prev => prev + 1);
|
||||
}, 1000);
|
||||
}
|
||||
return () => clearInterval(interval);
|
||||
}, [isTimerRunning]);
|
||||
|
||||
const formatTime = (seconds: number) => {
|
||||
const hours = Math.floor(seconds / 3600);
|
||||
const minutes = Math.floor((seconds % 3600) / 60);
|
||||
const secs = seconds % 60;
|
||||
return `${hours.toString().padStart(2, '0')}:${minutes
|
||||
.toString()
|
||||
.padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
const toggleTimer = () => {
|
||||
setIsTimerRunning(!isTimerRunning);
|
||||
};
|
||||
|
||||
const resetTimer = () => {
|
||||
setIsTimerRunning(false);
|
||||
setElapsedTime(0);
|
||||
setCurrentTask('');
|
||||
};
|
||||
|
||||
const timeEntries = [
|
||||
{
|
||||
id: '1',
|
||||
description: 'Mobile app development',
|
||||
duration: '2:30:00',
|
||||
date: 'Today',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
description: 'Code review',
|
||||
duration: '0:45:00',
|
||||
date: 'Yesterday',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Card style={styles.timerCard}>
|
||||
<Card.Content>
|
||||
<Title style={styles.timerTitle}>Time Tracker</Title>
|
||||
<Text style={styles.timeDisplay}>{formatTime(elapsedTime)}</Text>
|
||||
|
||||
{currentTask ? (
|
||||
<Paragraph style={styles.currentTask}>
|
||||
Working on: {currentTask}
|
||||
</Paragraph>
|
||||
) : (
|
||||
<Paragraph style={styles.noTask}>
|
||||
No task selected
|
||||
</Paragraph>
|
||||
)}
|
||||
|
||||
<View style={styles.timerButtons}>
|
||||
<Button
|
||||
mode={isTimerRunning ? 'outlined' : 'contained'}
|
||||
onPress={toggleTimer}
|
||||
style={styles.timerButton}
|
||||
>
|
||||
{isTimerRunning ? 'Pause' : 'Start'}
|
||||
</Button>
|
||||
<Button
|
||||
mode="outlined"
|
||||
onPress={resetTimer}
|
||||
style={styles.timerButton}
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
</View>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
<Card style={styles.entriesCard}>
|
||||
<Card.Content>
|
||||
<Title>Recent Entries</Title>
|
||||
{timeEntries.map(entry => (
|
||||
<View key={entry.id} style={styles.entryItem}>
|
||||
<View style={styles.entryContent}>
|
||||
<Text style={styles.entryDescription}>
|
||||
{entry.description}
|
||||
</Text>
|
||||
<Text style={styles.entryDuration}>
|
||||
{entry.duration}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.entryDate}>{entry.date}</Text>
|
||||
</View>
|
||||
))}
|
||||
</Card.Content>
|
||||
</Card>
|
||||
|
||||
<FAB
|
||||
icon="plus"
|
||||
style={styles.fab}
|
||||
onPress={() => console.log('Add time entry')}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#f5f5f5',
|
||||
padding: 16,
|
||||
},
|
||||
timerCard: {
|
||||
marginBottom: 16,
|
||||
elevation: 4,
|
||||
},
|
||||
timerTitle: {
|
||||
textAlign: 'center',
|
||||
marginBottom: 16,
|
||||
},
|
||||
timeDisplay: {
|
||||
fontSize: 48,
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'center',
|
||||
color: '#6200ee',
|
||||
marginBottom: 16,
|
||||
},
|
||||
currentTask: {
|
||||
textAlign: 'center',
|
||||
color: '#666',
|
||||
marginBottom: 16,
|
||||
},
|
||||
noTask: {
|
||||
textAlign: 'center',
|
||||
color: '#999',
|
||||
fontStyle: 'italic',
|
||||
marginBottom: 16,
|
||||
},
|
||||
timerButtons: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
},
|
||||
timerButton: {
|
||||
flex: 1,
|
||||
marginHorizontal: 8,
|
||||
},
|
||||
entriesCard: {
|
||||
elevation: 2,
|
||||
},
|
||||
entryItem: {
|
||||
paddingVertical: 12,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#eee',
|
||||
},
|
||||
entryContent: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
},
|
||||
entryDescription: {
|
||||
flex: 1,
|
||||
fontSize: 16,
|
||||
},
|
||||
entryDuration: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#6200ee',
|
||||
},
|
||||
entryDate: {
|
||||
fontSize: 12,
|
||||
color: '#666',
|
||||
marginTop: 4,
|
||||
},
|
||||
fab: {
|
||||
position: 'absolute',
|
||||
margin: 16,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: '#6200ee',
|
||||
},
|
||||
});
|
||||
|
||||
export default TimeTrackingScreen;
|
||||