feat(#7): категории напоминаний (exercise/hydration/eyes/posture)

This commit is contained in:
AnRil
2026-05-22 13:39:40 +07:00
parent 50c56fec79
commit 68998607e8
6 changed files with 117 additions and 11 deletions

View File

@@ -223,7 +223,7 @@ function ExerciseReminder({
</motion.div>
<div className="text-[13px] uppercase tracking-[0.18em] text-accent font-bold">
{t('reminder.kicker')}
{t(`category.${exercise.category ?? 'exercise'}.cta`)}
</div>
<h1 className="font-serif text-[30px] leading-tight tracking-tight mt-2 mb-3 font-bold">
{exercise.name}

View File

@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'
import type { Exercise } from '@shared/types'
import type { Exercise, ReminderCategory } from '@shared/types'
import { REMINDER_CATEGORIES } from '@shared/types'
import { Modal } from './ui/Modal'
import { Button } from './ui/Button'
import { ICON_CHOICES, Icon } from '../lib/icon'
@@ -11,6 +12,7 @@ type Draft = {
icon: string
intervalMinutes: number
enabled: boolean
category: ReminderCategory
}
const EMPTY: Draft = {
@@ -18,7 +20,8 @@ const EMPTY: Draft = {
reps: 10,
icon: 'Activity',
intervalMinutes: 30,
enabled: true
enabled: true,
category: 'exercise'
}
type Props = {
@@ -44,7 +47,8 @@ export function ExerciseEditor({
reps: exercise.reps,
icon: exercise.icon,
intervalMinutes: exercise.intervalMinutes,
enabled: exercise.enabled
enabled: exercise.enabled,
category: exercise.category ?? 'exercise'
})
} else {
setDraft(EMPTY)
@@ -101,6 +105,26 @@ export function ExerciseEditor({
/>
</Field>
<Field label={t('editor.field.category')}>
<div className="grid grid-cols-4 gap-2">
{REMINDER_CATEGORIES.map((c) => (
<button
key={c}
type="button"
onClick={() => setDraft({ ...draft, category: c })}
className={[
'h-10 px-2 rounded-xl text-[13px] font-semibold transition-all active:scale-95 truncate',
draft.category === c
? 'bg-accent text-white'
: 'bg-surface-2 text-text/65 hover:text-text'
].join(' ')}
>
{t(`category.${c}`)}
</button>
))}
</div>
</Field>
<div className="grid grid-cols-2 gap-3">
<Field label={t('editor.field.reps')}>
<input

View File

@@ -219,6 +219,17 @@ export const ru: Dict = {
'updater.idle.title': 'Проверить обновления',
'updater.idle.subtitle': 'Авто-проверка раз в час',
// Categories
'category.exercise': 'Упражнение',
'category.hydration': 'Гидратация',
'category.eyes': 'Отдых глазам',
'category.posture': 'Осанка',
'category.exercise.cta': 'Время тренировки',
'category.hydration.cta': 'Время попить',
'category.eyes.cta': 'Дай глазам отдохнуть',
'category.posture.cta': 'Проверь осанку',
'editor.field.category': 'Категория',
// Reminder window
'reminder.kicker': 'Время тренировки',
'reminder.subkicker': 'Двигайся',
@@ -484,6 +495,17 @@ export const en: Dict = {
'updater.idle.title': 'Check for updates',
'updater.idle.subtitle': 'Auto-check every hour',
// Categories
'category.exercise': 'Exercise',
'category.hydration': 'Hydration',
'category.eyes': 'Eye rest',
'category.posture': 'Posture',
'category.exercise.cta': 'Workout time',
'category.hydration.cta': 'Time to drink',
'category.eyes.cta': 'Rest your eyes',
'category.posture.cta': 'Check your posture',
'editor.field.category': 'Category',
// Reminder window
'reminder.kicker': 'Workout time',
'reminder.subkicker': 'Move',

View File

@@ -72,6 +72,7 @@ export default function Dashboard(): JSX.Element {
icon: string
intervalMinutes: number
enabled: boolean
category: import('@shared/types').ReminderCategory
}): Promise<void> {
if (editing) await window.api.updateExercise(editing.id, draft)
else await window.api.addExercise(draft)