4 Commits

Author SHA1 Message Date
jacobh2 81eadf618a Update gitignore
Build Frontend / build (push) Successful in 9m6s
2026-06-04 11:33:42 +02:00
jacobh2 6847886e7a chore: add vite environment type definitions 2026-06-04 11:33:21 +02:00
jacobh2 5d8a8b3c57 chore: update deployment and app structure 2026-06-04 11:31:44 +02:00
jacobh2 32d3e86d38 fix(frontend): resolve linting errors and component duplication 2026-06-04 11:30:18 +02:00
12 changed files with 59 additions and 23 deletions
+2
View File
@@ -51,6 +51,8 @@ jobs:
run: | run: |
docker buildx build \ docker buildx build \
--platform linux/arm64 \ --platform linux/arm64 \
--build-arg VITE_APP_VERSION=$(git describe --tags) \
--build-arg VITE_APP_GITSHA=$(git rev-parse --short HEAD) \
-t gitea.lan/jacobh2/babymonitor-frontend:${{ env.VERSION }} \ -t gitea.lan/jacobh2/babymonitor-frontend:${{ env.VERSION }} \
./frontend \ ./frontend \
--push --push
+2
View File
@@ -5,6 +5,8 @@
*.js *.js
*.jsx *.jsx
.omo/
### Node ### ### Node ###
# Logs # Logs
logs logs
+4
View File
@@ -1,5 +1,9 @@
FROM node:22-alpine AS build FROM node:22-alpine AS build
ARG VITE_APP_VERSION=unknown
ARG VITE_APP_GITSHA=unknown
ENV VITE_APP_VERSION=$VITE_APP_VERSION
ENV VITE_APP_GITSHA=$VITE_APP_GITSHA
WORKDIR /app WORKDIR /app
# Copy package files first to leverage Docker cache # Copy package files first to leverage Docker cache
+3
View File
@@ -4,6 +4,8 @@ import TrackerPage from './components/tracker/TrackerPage';
import StatsPage from './components/stats/StatsPage'; import StatsPage from './components/stats/StatsPage';
import Navbar from './components/Navbar'; import Navbar from './components/Navbar';
import Playground from './components/Playground'; import Playground from './components/Playground';
import Footer from './components/Footer';
function App() { function App() {
return ( return (
@@ -17,6 +19,7 @@ function App() {
<Route path="/playground" element={<Playground />} /> <Route path="/playground" element={<Playground />} />
</Routes> </Routes>
</main> </main>
<Footer />
</div> </div>
</Router> </Router>
); );
+13
View File
@@ -0,0 +1,13 @@
import React from 'react';
const Footer: React.FC = () => {
return (
<footer className="py-4 text-center">
<p className="text-xs text-slate-500">
v{__APP_VERSION__} ({__APP_GITSHA__})
</p>
</footer>
);
};
export default Footer;
@@ -100,8 +100,8 @@ const DailySummary: React.FC<DailySummaryProps> = ({ from_date, to_date, day_sta
width={60} width={60}
/> />
<Tooltip <Tooltip
formatter={(value: any, name: any) => [ formatter={(value: number | string | readonly (string | number)[] | undefined, name: string | number | undefined) => [
formatMinutes(Math.round(Number(value ?? 0) * 60)), formatMinutes(Math.round(Number((Array.isArray(value) ? value[0] : value ?? 0) * 60))),
name === 'daySleep' ? 'Day' : 'Night', name === 'daySleep' ? 'Day' : 'Night',
]} ]}
/> />
@@ -52,7 +52,8 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) =
useEffect(() => { useEffect(() => {
if (days.length > 0) { if (days.length > 0) {
setSelectedDayIndex(days.length - 1); const newIndex = days.length - 1;
setSelectedDayIndex(prev => (prev !== newIndex ? newIndex : prev));
} }
}, [days]); }, [days]);
@@ -158,7 +159,7 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) =
</button> </button>
); );
})} })}
</div > </div>
)} )}
{/* Grid Container */} {/* Grid Container */}
@@ -176,27 +177,27 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) =
{visibleDays.map((day) => ( {visibleDays.map((day) => (
<div key={day} className="text-center text-[10px] font-medium text-gray-500 uppercase flex items-center justify-center h-2"> <div key={day} className="text-center text-[10px] font-medium text-gray-500 uppercase flex items-center justify-center h-2">
{getDayName(day)} {getDayName(day)}
</div > </div>
))} ))}
</div > </div>
{/* Time Grid Container */} {/* Time Grid Container */}
<div className="relative"> <div className="relative">
<div <div
className="grid" className="grid"
style={{ style={{
gridTemplateColumns: tier === 'desktop' gridTemplateColumns: tier === 'desktop'
? `4rem repeat(${days.length}, minmax(40px, 1fr))` ? `4rem repeat(${days.length}, minmax(40px, 1fr))`
: `4rem repeat(${visibleDays.length}, 1fr)` : `4rem repeat(${visibleDays.length}, 1fr)`
}} }}
> >
{/* Time Rows */} {/* Time Rows */}
{timeSteps.map((step) => ( {timeSteps.map((step) => (
<Fragment key={step}> <Fragment key={step}>
{/* Time Label */} {/* Time Label */}
<div className="text-[10px] text-gray-400 flex items-center justify-end pr-2 h-2"> <div className="text-[10px] text-gray-400 flex items-center justify-end pr-2 h-2">
{step % 60 === 0 ? formatTimeLabel(step) : ''} {step % 60 === 0 ? formatTimeLabel(step) : ''}
</div > </div>
{/* Grid Cells */} {/* Grid Cells */}
{visibleDays.map((day) => { {visibleDays.map((day) => {
@@ -220,11 +221,11 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) =
transform: 'translateY(-50%)' transform: 'translateY(-50%)'
}} }}
/> />
</div > </div>
</div > </div>
</div > </div>
</div > </div>
); );
}; };
export default Timetable; export default Timetable;
+1 -1
View File
@@ -1,4 +1,4 @@
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react'; import { createContext, useState, useEffect, ReactNode } from 'react';
const STORAGE_KEY = 'baby-sleep-settings'; const STORAGE_KEY = 'baby-sleep-settings';
+1 -1
View File
@@ -1,5 +1,5 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { SettingsContext, Settings } from './SettingsProvider'; import { SettingsContext } from './SettingsProvider';
export function useSettings() { export function useSettings() {
const context = useContext(SettingsContext); const context = useContext(SettingsContext);
+4
View File
@@ -0,0 +1,4 @@
/// <reference types="vite/client" />
declare const __APP_VERSION__: string;
declare const __APP_GITSHA__: string;
+7
View File
@@ -3,9 +3,16 @@ import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite' import tailwindcss from '@tailwindcss/vite'
import path from 'path' import path from 'path'
const APP_VERSION = process.env.VITE_APP_VERSION || 'unknown';
const APP_GITSHA = process.env.VITE_APP_GITSHA || 'unknown';
export default defineConfig({ export default defineConfig({
base: './', base: './',
plugins: [react(), tailwindcss()], plugins: [react(), tailwindcss()],
define: {
__APP_VERSION__: JSON.stringify(APP_VERSION),
__APP_GITSHA__: JSON.stringify(APP_GITSHA),
},
resolve: { resolve: {
alias: { alias: {
'@': path.resolve(__dirname, './src'), '@': path.resolve(__dirname, './src'),
+2 -2
View File
@@ -19,9 +19,9 @@ exitcode '1': failure
``` ```
- [ ] Editing a sleep session in "sleep sessions", when I click the edit button the times show up as UTC but should show as my local timezone - [ ] Editing a sleep session in "sleep sessions", when I click the edit button the times show up as UTC but should show as my local timezone
- [ ] We should drop the "notes" column from the sleep_session table - [/] We should drop the "notes" column from the sleep_session table
- [x] Switch over to oh-my-opencode and try it out - [x] Switch over to oh-my-opencode and try it out
- [/] Adda footer at the bottom of the app that shows the version (aka git tag) of the app - [x] Adda footer at the bottom of the app that shows the version (aka git tag) of the app
- [-] Fix race condition of gitea workflows - [-] Fix race condition of gitea workflows
If both workflows run at the same time, a race condition occurs: If both workflows run at the same time, a race condition occurs: