@even-toolkit/create-even-app 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +159 -0
- package/package.json +28 -0
- package/templates/chat/README.md +27 -0
- package/templates/chat/index.html +12 -0
- package/templates/chat/package.json +34 -0
- package/templates/chat/src/App.tsx +61 -0
- package/templates/chat/src/app.css +54 -0
- package/templates/chat/src/contexts/ChatContext.tsx +99 -0
- package/templates/chat/src/glass/AppGlasses.tsx +70 -0
- package/templates/chat/src/glass/screens/home.ts +24 -0
- package/templates/chat/src/glass/selectors.ts +9 -0
- package/templates/chat/src/glass/shared.ts +8 -0
- package/templates/chat/src/glass/splash.ts +25 -0
- package/templates/chat/src/main.tsx +13 -0
- package/templates/chat/src/screens/ChatScreen.tsx +69 -0
- package/templates/chat/src/screens/Settings.tsx +88 -0
- package/templates/chat/src/types.ts +13 -0
- package/templates/chat/src/vite-env.d.ts +1 -0
- package/templates/chat/template.json +7 -0
- package/templates/chat/tsconfig.json +20 -0
- package/templates/chat/tsconfig.node.json +13 -0
- package/templates/chat/vite.config.ts +12 -0
- package/templates/dashboard/README.md +17 -0
- package/templates/dashboard/index.html +12 -0
- package/templates/dashboard/package.json +34 -0
- package/templates/dashboard/src/App.tsx +27 -0
- package/templates/dashboard/src/app.css +54 -0
- package/templates/dashboard/src/glass/AppGlasses.tsx +53 -0
- package/templates/dashboard/src/glass/screens/home.ts +23 -0
- package/templates/dashboard/src/glass/selectors.ts +9 -0
- package/templates/dashboard/src/glass/shared.ts +8 -0
- package/templates/dashboard/src/glass/splash.ts +22 -0
- package/templates/dashboard/src/main.tsx +13 -0
- package/templates/dashboard/src/screens/ChartsScreen.tsx +99 -0
- package/templates/dashboard/src/screens/OverviewScreen.tsx +102 -0
- package/templates/dashboard/src/screens/SettingsScreen.tsx +60 -0
- package/templates/dashboard/src/vite-env.d.ts +1 -0
- package/templates/dashboard/template.json +7 -0
- package/templates/dashboard/tsconfig.json +20 -0
- package/templates/dashboard/tsconfig.node.json +13 -0
- package/templates/dashboard/vite.config.ts +12 -0
- package/templates/media/README.md +27 -0
- package/templates/media/index.html +12 -0
- package/templates/media/package.json +34 -0
- package/templates/media/src/App.tsx +24 -0
- package/templates/media/src/app.css +54 -0
- package/templates/media/src/contexts/MediaContext.tsx +108 -0
- package/templates/media/src/glass/AppGlasses.tsx +59 -0
- package/templates/media/src/glass/screens/home.ts +24 -0
- package/templates/media/src/glass/selectors.ts +9 -0
- package/templates/media/src/glass/shared.ts +8 -0
- package/templates/media/src/glass/splash.ts +25 -0
- package/templates/media/src/layouts/shell.tsx +39 -0
- package/templates/media/src/main.tsx +13 -0
- package/templates/media/src/screens/AudioScreen.tsx +78 -0
- package/templates/media/src/screens/GalleryScreen.tsx +98 -0
- package/templates/media/src/screens/Settings.tsx +86 -0
- package/templates/media/src/screens/UploadScreen.tsx +95 -0
- package/templates/media/src/types.ts +29 -0
- package/templates/media/src/vite-env.d.ts +1 -0
- package/templates/media/template.json +7 -0
- package/templates/media/tsconfig.json +20 -0
- package/templates/media/tsconfig.node.json +13 -0
- package/templates/media/vite.config.ts +12 -0
- package/templates/minimal/README.md +27 -0
- package/templates/minimal/index.html +12 -0
- package/templates/minimal/package.json +34 -0
- package/templates/minimal/src/App.tsx +50 -0
- package/templates/minimal/src/app.css +54 -0
- package/templates/minimal/src/glass/AppGlasses.tsx +54 -0
- package/templates/minimal/src/glass/screens/home.ts +24 -0
- package/templates/minimal/src/glass/selectors.ts +9 -0
- package/templates/minimal/src/glass/shared.ts +8 -0
- package/templates/minimal/src/glass/splash.ts +25 -0
- package/templates/minimal/src/main.tsx +13 -0
- package/templates/minimal/src/vite-env.d.ts +1 -0
- package/templates/minimal/template.json +7 -0
- package/templates/minimal/tsconfig.json +20 -0
- package/templates/minimal/tsconfig.node.json +13 -0
- package/templates/minimal/vite.config.ts +12 -0
- package/templates/notes/README.md +27 -0
- package/templates/notes/index.html +12 -0
- package/templates/notes/package.json +34 -0
- package/templates/notes/src/App.tsx +25 -0
- package/templates/notes/src/app.css +54 -0
- package/templates/notes/src/contexts/NotesContext.tsx +140 -0
- package/templates/notes/src/glass/AppGlasses.tsx +58 -0
- package/templates/notes/src/glass/screens/home.ts +24 -0
- package/templates/notes/src/glass/selectors.ts +9 -0
- package/templates/notes/src/glass/shared.ts +8 -0
- package/templates/notes/src/glass/splash.ts +24 -0
- package/templates/notes/src/layouts/shell.tsx +36 -0
- package/templates/notes/src/main.tsx +13 -0
- package/templates/notes/src/screens/NoteDetail.tsx +104 -0
- package/templates/notes/src/screens/NoteForm.tsx +84 -0
- package/templates/notes/src/screens/NoteList.tsx +108 -0
- package/templates/notes/src/screens/Settings.tsx +88 -0
- package/templates/notes/src/types.ts +14 -0
- package/templates/notes/src/vite-env.d.ts +1 -0
- package/templates/notes/template.json +7 -0
- package/templates/notes/tsconfig.json +20 -0
- package/templates/notes/tsconfig.node.json +13 -0
- package/templates/notes/vite.config.ts +12 -0
- package/templates/tracker/README.md +27 -0
- package/templates/tracker/index.html +12 -0
- package/templates/tracker/package.json +34 -0
- package/templates/tracker/src/App.tsx +24 -0
- package/templates/tracker/src/app.css +54 -0
- package/templates/tracker/src/contexts/TrackerContext.tsx +193 -0
- package/templates/tracker/src/glass/AppGlasses.tsx +64 -0
- package/templates/tracker/src/glass/screens/home.ts +24 -0
- package/templates/tracker/src/glass/selectors.ts +9 -0
- package/templates/tracker/src/glass/shared.ts +8 -0
- package/templates/tracker/src/glass/splash.ts +24 -0
- package/templates/tracker/src/layouts/shell.tsx +37 -0
- package/templates/tracker/src/main.tsx +13 -0
- package/templates/tracker/src/screens/HistoryScreen.tsx +106 -0
- package/templates/tracker/src/screens/NewEntryScreen.tsx +135 -0
- package/templates/tracker/src/screens/Settings.tsx +135 -0
- package/templates/tracker/src/screens/TodayScreen.tsx +147 -0
- package/templates/tracker/src/types.ts +34 -0
- package/templates/tracker/src/vite-env.d.ts +1 -0
- package/templates/tracker/template.json +7 -0
- package/templates/tracker/tsconfig.json +20 -0
- package/templates/tracker/tsconfig.node.json +13 -0
- package/templates/tracker/vite.config.ts +12 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import { SettingsGroup, Toggle, ListItem, Card, Button, Divider, Input, useDrawerHeader } from 'even-toolkit/web'
|
|
3
|
+
import { useTracker } from '../contexts/TrackerContext'
|
|
4
|
+
|
|
5
|
+
export function Settings() {
|
|
6
|
+
const { goals, setGoals, entries, showCompletionBadge, setShowCompletionBadge } = useTracker()
|
|
7
|
+
const [confirmClear, setConfirmClear] = useState(false)
|
|
8
|
+
|
|
9
|
+
const [waterGoal, setWaterGoal] = useState(String(goals.water))
|
|
10
|
+
const [stepsGoal, setStepsGoal] = useState(String(goals.steps))
|
|
11
|
+
const [focusGoal, setFocusGoal] = useState(String(goals.focus))
|
|
12
|
+
|
|
13
|
+
useDrawerHeader({ title: 'Settings', backTo: '/' })
|
|
14
|
+
|
|
15
|
+
function handleSaveGoals() {
|
|
16
|
+
const w = parseInt(waterGoal, 10)
|
|
17
|
+
const s = parseInt(stepsGoal, 10)
|
|
18
|
+
const f = parseInt(focusGoal, 10)
|
|
19
|
+
if (!isNaN(w) && !isNaN(s) && !isNaN(f) && w > 0 && s > 0 && f > 0) {
|
|
20
|
+
setGoals({ water: w, steps: s, focus: f })
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function handleExport() {
|
|
25
|
+
const data = JSON.stringify(entries, null, 2)
|
|
26
|
+
const blob = new Blob([data], { type: 'application/json' })
|
|
27
|
+
const url = URL.createObjectURL(blob)
|
|
28
|
+
const a = document.createElement('a')
|
|
29
|
+
a.href = url
|
|
30
|
+
a.download = `tracker-export-${Date.now()}.json`
|
|
31
|
+
a.click()
|
|
32
|
+
URL.revokeObjectURL(url)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function handleClearAll() {
|
|
36
|
+
if (!confirmClear) {
|
|
37
|
+
setConfirmClear(true)
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
localStorage.removeItem('{{APP_NAME}}-entries')
|
|
41
|
+
localStorage.removeItem('{{APP_NAME}}-goals')
|
|
42
|
+
localStorage.removeItem('{{APP_NAME}}-settings')
|
|
43
|
+
window.location.reload()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<main className="px-3 pt-4 pb-8 space-y-6">
|
|
48
|
+
<SettingsGroup label="Goals">
|
|
49
|
+
<Card className="p-4 space-y-3">
|
|
50
|
+
<div className="space-y-1.5">
|
|
51
|
+
<label className="text-[11px] tracking-[-0.11px] text-text-dim block">Water (glasses per day)</label>
|
|
52
|
+
<Input
|
|
53
|
+
type="number"
|
|
54
|
+
value={waterGoal}
|
|
55
|
+
onChange={(e) => setWaterGoal(e.target.value)}
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
58
|
+
<div className="space-y-1.5">
|
|
59
|
+
<label className="text-[11px] tracking-[-0.11px] text-text-dim block">Steps (per day)</label>
|
|
60
|
+
<Input
|
|
61
|
+
type="number"
|
|
62
|
+
value={stepsGoal}
|
|
63
|
+
onChange={(e) => setStepsGoal(e.target.value)}
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
<div className="space-y-1.5">
|
|
67
|
+
<label className="text-[11px] tracking-[-0.11px] text-text-dim block">Focus (minutes per day)</label>
|
|
68
|
+
<Input
|
|
69
|
+
type="number"
|
|
70
|
+
value={focusGoal}
|
|
71
|
+
onChange={(e) => setFocusGoal(e.target.value)}
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
<Button size="sm" onClick={handleSaveGoals}>
|
|
75
|
+
Save Goals
|
|
76
|
+
</Button>
|
|
77
|
+
</Card>
|
|
78
|
+
</SettingsGroup>
|
|
79
|
+
|
|
80
|
+
<SettingsGroup label="Display">
|
|
81
|
+
<Card className="p-4">
|
|
82
|
+
<div className="flex items-center justify-between">
|
|
83
|
+
<div>
|
|
84
|
+
<p className="text-[15px] tracking-[-0.15px] text-text">Completion Badge</p>
|
|
85
|
+
<p className="text-[11px] tracking-[-0.11px] text-text-dim mt-0.5">
|
|
86
|
+
Show daily completion percentage in history
|
|
87
|
+
</p>
|
|
88
|
+
</div>
|
|
89
|
+
<Toggle checked={showCompletionBadge} onChange={setShowCompletionBadge} />
|
|
90
|
+
</div>
|
|
91
|
+
</Card>
|
|
92
|
+
</SettingsGroup>
|
|
93
|
+
|
|
94
|
+
<SettingsGroup label="Data">
|
|
95
|
+
<Card className="divide-y divide-border">
|
|
96
|
+
<ListItem
|
|
97
|
+
title="Export Data"
|
|
98
|
+
subtitle={`Export all ${entries.length} entries as JSON`}
|
|
99
|
+
onPress={handleExport}
|
|
100
|
+
/>
|
|
101
|
+
<div>
|
|
102
|
+
<ListItem
|
|
103
|
+
title={confirmClear ? 'Tap again to confirm' : 'Clear All Data'}
|
|
104
|
+
subtitle="Permanently delete all entries and reset goals"
|
|
105
|
+
onPress={handleClearAll}
|
|
106
|
+
/>
|
|
107
|
+
{confirmClear && (
|
|
108
|
+
<div className="px-4 pb-3">
|
|
109
|
+
<Button
|
|
110
|
+
variant="ghost"
|
|
111
|
+
size="sm"
|
|
112
|
+
className="w-full"
|
|
113
|
+
onClick={() => setConfirmClear(false)}
|
|
114
|
+
>
|
|
115
|
+
Cancel
|
|
116
|
+
</Button>
|
|
117
|
+
</div>
|
|
118
|
+
)}
|
|
119
|
+
</div>
|
|
120
|
+
</Card>
|
|
121
|
+
</SettingsGroup>
|
|
122
|
+
|
|
123
|
+
<SettingsGroup label="About">
|
|
124
|
+
<Card className="p-4 space-y-1.5">
|
|
125
|
+
<p className="text-[15px] tracking-[-0.15px] text-text">{{DISPLAY_NAME}}</p>
|
|
126
|
+
<p className="text-[13px] tracking-[-0.13px] text-text-dim">Version 1.0.0</p>
|
|
127
|
+
<Divider className="my-2" />
|
|
128
|
+
<p className="text-[11px] tracking-[-0.11px] text-text-dim">
|
|
129
|
+
An activity and habit tracker for Even Realities G2 smart glasses. All data is stored locally in your browser.
|
|
130
|
+
</p>
|
|
131
|
+
</Card>
|
|
132
|
+
</SettingsGroup>
|
|
133
|
+
</main>
|
|
134
|
+
)
|
|
135
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from 'react'
|
|
2
|
+
import { useNavigate } from 'react-router'
|
|
3
|
+
import { Card, Button, Progress, StatusProgress, TimerRing, StatGrid, ScreenHeader, useDrawerHeader } from 'even-toolkit/web'
|
|
4
|
+
import { IcPlus } from 'even-toolkit/web/icons/svg-icons'
|
|
5
|
+
import { useTracker } from '../contexts/TrackerContext'
|
|
6
|
+
|
|
7
|
+
function formatPercent(value: number, target: number): string {
|
|
8
|
+
return `${Math.round((value / target) * 100)}%`
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function TodayScreen() {
|
|
12
|
+
const navigate = useNavigate()
|
|
13
|
+
const { goals, getTodayTotal } = useTracker()
|
|
14
|
+
|
|
15
|
+
const waterTotal = getTodayTotal('Water')
|
|
16
|
+
const stepsTotal = getTodayTotal('Steps')
|
|
17
|
+
const focusTotal = getTodayTotal('Focus')
|
|
18
|
+
|
|
19
|
+
// Focus timer state
|
|
20
|
+
const [timerActive, setTimerActive] = useState(false)
|
|
21
|
+
const [timerRemaining, setTimerRemaining] = useState(25 * 60) // 25 min default
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (!timerActive || timerRemaining <= 0) return
|
|
25
|
+
const interval = setInterval(() => {
|
|
26
|
+
setTimerRemaining((prev) => {
|
|
27
|
+
if (prev <= 1) {
|
|
28
|
+
setTimerActive(false)
|
|
29
|
+
return 0
|
|
30
|
+
}
|
|
31
|
+
return prev - 1
|
|
32
|
+
})
|
|
33
|
+
}, 1000)
|
|
34
|
+
return () => clearInterval(interval)
|
|
35
|
+
}, [timerActive, timerRemaining])
|
|
36
|
+
|
|
37
|
+
const toggleTimer = useCallback(() => {
|
|
38
|
+
if (timerRemaining <= 0) {
|
|
39
|
+
setTimerRemaining(25 * 60)
|
|
40
|
+
setTimerActive(true)
|
|
41
|
+
} else {
|
|
42
|
+
setTimerActive((prev) => !prev)
|
|
43
|
+
}
|
|
44
|
+
}, [timerRemaining])
|
|
45
|
+
|
|
46
|
+
// Routine steps
|
|
47
|
+
const hour = new Date().getHours()
|
|
48
|
+
const routineSteps = [
|
|
49
|
+
{ label: 'Morning', status: hour >= 9 ? 'complete' as const : hour >= 6 ? 'in-progress' as const : 'waiting' as const },
|
|
50
|
+
{ label: 'Work', status: hour >= 17 ? 'complete' as const : hour >= 9 ? 'in-progress' as const : 'waiting' as const },
|
|
51
|
+
{ label: 'Exercise', status: stepsTotal >= goals.steps ? 'complete' as const : hour >= 17 ? 'in-progress' as const : 'waiting' as const },
|
|
52
|
+
{ label: 'Evening', status: hour >= 21 ? 'complete' as const : hour >= 19 ? 'in-progress' as const : 'waiting' as const },
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
useDrawerHeader({
|
|
56
|
+
right: (
|
|
57
|
+
<Button variant="ghost" size="icon" onClick={() => navigate('/new')}>
|
|
58
|
+
<IcPlus width={20} height={20} />
|
|
59
|
+
</Button>
|
|
60
|
+
),
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<main className="px-3 pt-4 pb-8 space-y-3">
|
|
65
|
+
<ScreenHeader
|
|
66
|
+
title="Today"
|
|
67
|
+
subtitle={new Date().toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' })}
|
|
68
|
+
/>
|
|
69
|
+
|
|
70
|
+
{/* Daily Goals Progress */}
|
|
71
|
+
<Card className="p-4 space-y-3">
|
|
72
|
+
<p className="text-[15px] tracking-[-0.15px] text-text">Daily Goals</p>
|
|
73
|
+
|
|
74
|
+
<div className="space-y-3">
|
|
75
|
+
<div className="space-y-1.5">
|
|
76
|
+
<div className="flex items-center justify-between">
|
|
77
|
+
<span className="text-[13px] tracking-[-0.13px] text-text">Water</span>
|
|
78
|
+
<span className="text-[13px] tracking-[-0.13px] text-text-dim">
|
|
79
|
+
{waterTotal}/{goals.water} glasses
|
|
80
|
+
</span>
|
|
81
|
+
</div>
|
|
82
|
+
<Progress value={(waterTotal / goals.water) * 100} />
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<div className="space-y-1.5">
|
|
86
|
+
<div className="flex items-center justify-between">
|
|
87
|
+
<span className="text-[13px] tracking-[-0.13px] text-text">Steps</span>
|
|
88
|
+
<span className="text-[13px] tracking-[-0.13px] text-text-dim">
|
|
89
|
+
{stepsTotal.toLocaleString()}/{goals.steps.toLocaleString()}
|
|
90
|
+
</span>
|
|
91
|
+
</div>
|
|
92
|
+
<Progress value={(stepsTotal / goals.steps) * 100} />
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<div className="space-y-1.5">
|
|
96
|
+
<div className="flex items-center justify-between">
|
|
97
|
+
<span className="text-[13px] tracking-[-0.13px] text-text">Focus</span>
|
|
98
|
+
<span className="text-[13px] tracking-[-0.13px] text-text-dim">
|
|
99
|
+
{focusTotal}/{goals.focus} min
|
|
100
|
+
</span>
|
|
101
|
+
</div>
|
|
102
|
+
<Progress value={(focusTotal / goals.focus) * 100} />
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</Card>
|
|
106
|
+
|
|
107
|
+
{/* Daily Routine */}
|
|
108
|
+
<Card className="p-4 space-y-3">
|
|
109
|
+
<p className="text-[15px] tracking-[-0.15px] text-text">Daily Routine</p>
|
|
110
|
+
<StatusProgress steps={routineSteps} />
|
|
111
|
+
</Card>
|
|
112
|
+
|
|
113
|
+
{/* Focus Timer */}
|
|
114
|
+
<Card className="p-4 space-y-3">
|
|
115
|
+
<p className="text-[15px] tracking-[-0.15px] text-text">Focus Timer</p>
|
|
116
|
+
<div className="flex flex-col items-center gap-3">
|
|
117
|
+
<TimerRing
|
|
118
|
+
remaining={timerRemaining}
|
|
119
|
+
total={25 * 60}
|
|
120
|
+
size={140}
|
|
121
|
+
strokeWidth={6}
|
|
122
|
+
/>
|
|
123
|
+
<Button
|
|
124
|
+
size="sm"
|
|
125
|
+
variant={timerActive ? 'secondary' : 'default'}
|
|
126
|
+
onClick={toggleTimer}
|
|
127
|
+
>
|
|
128
|
+
{timerRemaining <= 0 ? 'Restart' : timerActive ? 'Pause' : 'Start Focus'}
|
|
129
|
+
</Button>
|
|
130
|
+
</div>
|
|
131
|
+
</Card>
|
|
132
|
+
|
|
133
|
+
{/* Today's Stats */}
|
|
134
|
+
<Card className="p-4 space-y-3">
|
|
135
|
+
<p className="text-[15px] tracking-[-0.15px] text-text">Stats</p>
|
|
136
|
+
<StatGrid
|
|
137
|
+
columns={3}
|
|
138
|
+
stats={[
|
|
139
|
+
{ label: 'Water', value: formatPercent(waterTotal, goals.water) },
|
|
140
|
+
{ label: 'Steps', value: formatPercent(stepsTotal, goals.steps) },
|
|
141
|
+
{ label: 'Focus', value: formatPercent(focusTotal, goals.focus) },
|
|
142
|
+
]}
|
|
143
|
+
/>
|
|
144
|
+
</Card>
|
|
145
|
+
</main>
|
|
146
|
+
)
|
|
147
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type ActivityType = 'Water' | 'Steps' | 'Focus'
|
|
2
|
+
|
|
3
|
+
export interface TrackerEntry {
|
|
4
|
+
id: string
|
|
5
|
+
activity: ActivityType
|
|
6
|
+
value: number
|
|
7
|
+
note: string
|
|
8
|
+
timestamp: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface DayRecord {
|
|
12
|
+
date: string // YYYY-MM-DD
|
|
13
|
+
entries: TrackerEntry[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface GoalTargets {
|
|
17
|
+
water: number // glasses
|
|
18
|
+
steps: number // steps
|
|
19
|
+
focus: number // minutes
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const ACTIVITIES: ActivityType[] = ['Water', 'Steps', 'Focus']
|
|
23
|
+
|
|
24
|
+
export const DEFAULT_GOALS: GoalTargets = {
|
|
25
|
+
water: 8,
|
|
26
|
+
steps: 10000,
|
|
27
|
+
focus: 60,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const ACTIVITY_UNITS: Record<ActivityType, string> = {
|
|
31
|
+
Water: 'glasses',
|
|
32
|
+
Steps: 'steps',
|
|
33
|
+
Focus: 'min',
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tracker",
|
|
3
|
+
"displayName": "Activity Tracker",
|
|
4
|
+
"description": "Activity and habit tracker with daily goals, history calendar, and focus timer — built for G2 smart glasses",
|
|
5
|
+
"tags": ["tracker", "habits", "health"],
|
|
6
|
+
"components": ["DrawerShell", "ScreenHeader", "Card", "Button", "Progress", "StatusProgress", "TimerRing", "StatGrid", "Calendar", "Timeline", "StepIndicator", "Select", "Slider", "Input", "Textarea", "Badge", "SettingsGroup", "Toggle", "Divider", "ListItem"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"isolatedModules": true,
|
|
15
|
+
"baseUrl": ".",
|
|
16
|
+
"paths": { "@/*": ["./src/*"] }
|
|
17
|
+
},
|
|
18
|
+
"include": ["src"],
|
|
19
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import react from '@vitejs/plugin-react'
|
|
3
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
4
|
+
import path from 'path'
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
plugins: [react(), tailwindcss()],
|
|
8
|
+
resolve: {
|
|
9
|
+
alias: { '@': path.resolve(__dirname, './src') },
|
|
10
|
+
dedupe: ['react', 'react-dom', 'react-router', '@evenrealities/even_hub_sdk', '@jappyjan/even-better-sdk', 'upng-js'],
|
|
11
|
+
},
|
|
12
|
+
})
|