feat: Add package type support and per-intake takenBy (#89)
## Package Type Feature - Add 'blister' and 'bottle' package types for medications - Bottle type uses totalPills for capacity and looseTablets for current stock - Blister type continues to use packCount/blistersPerPack/pillsPerBlister - Add doseUnit field for flexible dosing (mg, ml, IU, etc.) - Full UI support in medication form and detail modal ## Per-Intake TakenBy - Move takenBy from medication level to individual intakes - Each intake schedule can now be assigned to a different person - Update scheduler-utils to handle per-intake takenBy - Update SharedSchedule to filter by per-intake takenBy - Backward compatible with existing medication data ## UI Improvements - Add PasswordInput component with show/hide toggle - Centralize stockThresholds in AppContext for consistent status display - Fix SharedSchedule sync issues with per-intake takenBy - Improve mobile editing experience ## Technical - Add migrations 0004 and 0005 for schema changes - Update all relevant tests (1064 tests passing) - Maintain backward compatibility with ALTER migrations
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { createContext, type ReactNode, useCallback, useContext, useEffect, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ConfirmModal } from "./ConfirmModal";
|
||||
import { PasswordInput } from "./PasswordInput";
|
||||
|
||||
// =============================================================================
|
||||
// Types (no roles - all users are equal)
|
||||
@@ -402,9 +403,8 @@ export function LoginForm({
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="password">{t("auth.password", "Password")}</label>
|
||||
<input
|
||||
<PasswordInput
|
||||
id="password"
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
@@ -522,9 +522,8 @@ export function RegisterForm({ onSuccess, onSwitchToLogin }: { onSuccess?: () =>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="password">{t("auth.password", "Password")} *</label>
|
||||
<input
|
||||
<PasswordInput
|
||||
id="password"
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
@@ -536,9 +535,8 @@ export function RegisterForm({ onSuccess, onSwitchToLogin }: { onSuccess?: () =>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="confirmPassword">{t("auth.confirmPassword", "Confirm Password")} *</label>
|
||||
<input
|
||||
<PasswordInput
|
||||
id="confirmPassword"
|
||||
type="password"
|
||||
value={confirmPassword}
|
||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
||||
required
|
||||
@@ -722,9 +720,8 @@ export function UserProfile({ onClose }: { onClose?: () => void }) {
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="current-password">{t("auth.currentPassword", "Current Password")}</label>
|
||||
<input
|
||||
<PasswordInput
|
||||
id="current-password"
|
||||
type="password"
|
||||
value={currentPassword}
|
||||
onChange={(e) => setCurrentPassword(e.target.value)}
|
||||
autoComplete="current-password"
|
||||
@@ -734,9 +731,8 @@ export function UserProfile({ onClose }: { onClose?: () => void }) {
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="new-password">{t("auth.newPassword", "New Password")}</label>
|
||||
<input
|
||||
<PasswordInput
|
||||
id="new-password"
|
||||
type="password"
|
||||
value={newPassword}
|
||||
onChange={(e) => setNewPassword(e.target.value)}
|
||||
autoComplete="new-password"
|
||||
@@ -747,9 +743,8 @@ export function UserProfile({ onClose }: { onClose?: () => void }) {
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="confirm-new-password">{t("auth.confirmPassword", "Confirm Password")}</label>
|
||||
<input
|
||||
<PasswordInput
|
||||
id="confirm-new-password"
|
||||
type="password"
|
||||
value={confirmPassword}
|
||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
||||
autoComplete="new-password"
|
||||
|
||||
Reference in New Issue
Block a user