try to do better #18
@@ -1,4 +1,5 @@
|
|||||||
import React, { Component, ReactNode } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
import { AlertTriangle } from 'lucide-react';
|
import { AlertTriangle } from 'lucide-react';
|
||||||
import { Button } from './ui';
|
import { Button } from './ui';
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ export class ErrorBoundary extends Component<Props, State> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static getDerivedStateFromError(error: Error): Partial<State> {
|
static getDerivedStateFromError(_error: Error): Partial<State> {
|
||||||
return { hasError: true };
|
return { hasError: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ export class ErrorBoundary extends Component<Props, State> {
|
|||||||
<p className="text-gray-600 dark:text-gray-400 mb-6">
|
<p className="text-gray-600 dark:text-gray-400 mb-6">
|
||||||
We're sorry, but something unexpected happened. Please try refreshing the page or going back to the home page.
|
We're sorry, but something unexpected happened. Please try refreshing the page or going back to the home page.
|
||||||
</p>
|
</p>
|
||||||
{process.env.NODE_ENV === 'development' && this.state.error && (
|
{import.meta.env.DEV && this.state.error && (
|
||||||
<div className="mb-6 p-4 bg-red-50 dark:bg-red-900/10 rounded-lg text-left">
|
<div className="mb-6 p-4 bg-red-50 dark:bg-red-900/10 rounded-lg text-left">
|
||||||
<p className="text-sm font-mono text-red-800 dark:text-red-300 break-all">
|
<p className="text-sm font-mono text-red-800 dark:text-red-300 break-all">
|
||||||
{this.state.error.toString()}
|
{this.state.error.toString()}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { useState } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ShoppingCart, CheckCheck, Trash2 } from 'lucide-react';
|
import { ShoppingCart, CheckCheck, Trash2 } from 'lucide-react';
|
||||||
import { useShoppingList, useConfirm } from '../hooks';
|
import { useShoppingList, useConfirm } from '../hooks';
|
||||||
@@ -16,7 +15,6 @@ export default function ShoppingListModal({ familyId, onClose }: ShoppingListMod
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { items, loading, createItem, deleteItem, togglePurchased, markAllAsPurchased, clearAll } = useShoppingList(familyId);
|
const { items, loading, createItem, deleteItem, togglePurchased, markAllAsPurchased, clearAll } = useShoppingList(familyId);
|
||||||
const { confirmState, confirm, cancel } = useConfirm();
|
const { confirmState, confirm, cancel } = useConfirm();
|
||||||
const [pendingAction, setPendingAction] = useState<{ type: 'delete' | 'markAll' | 'clearAll'; itemId?: number } | null>(null);
|
|
||||||
|
|
||||||
const stats = shoppingService.getStats(items);
|
const stats = shoppingService.getStats(items);
|
||||||
|
|
||||||
@@ -25,24 +23,18 @@ export default function ShoppingListModal({ familyId, onClose }: ShoppingListMod
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = async (itemId: number) => {
|
const handleDelete = async (itemId: number) => {
|
||||||
setPendingAction({ type: 'delete', itemId });
|
|
||||||
await confirm(t('shopping.deleteConfirm'), t('shopping.deleteMessage'));
|
await confirm(t('shopping.deleteConfirm'), t('shopping.deleteMessage'));
|
||||||
await deleteItem(itemId);
|
await deleteItem(itemId);
|
||||||
setPendingAction(null);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMarkAll = async () => {
|
const handleMarkAll = async () => {
|
||||||
setPendingAction({ type: 'markAll' });
|
|
||||||
await confirm(t('shopping.markAllConfirm'), t('shopping.markAllMessage'));
|
await confirm(t('shopping.markAllConfirm'), t('shopping.markAllMessage'));
|
||||||
await markAllAsPurchased();
|
await markAllAsPurchased();
|
||||||
setPendingAction(null);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClearAll = async () => {
|
const handleClearAll = async () => {
|
||||||
setPendingAction({ type: 'clearAll' });
|
|
||||||
await confirm(t('shopping.clearAllConfirm'), t('shopping.clearAllMessage'));
|
await confirm(t('shopping.clearAllConfirm'), t('shopping.clearAllMessage'));
|
||||||
await clearAll();
|
await clearAll();
|
||||||
setPendingAction(null);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdate = async (itemId: number, name: string) => {
|
const handleUpdate = async (itemId: number, name: string) => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Plus, X } from 'lucide-react';
|
import { Plus, X } from 'lucide-react';
|
||||||
import { Button, Input } from '../ui';
|
import { Button, Input } from '../ui';
|
||||||
import { CreateCategoryRequest } from '../../types';
|
import type { CreateCategoryRequest } from '../../types';
|
||||||
|
|
||||||
interface AddCategorySectionProps {
|
interface AddCategorySectionProps {
|
||||||
showForm: boolean;
|
showForm: boolean;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Tag, TrendingDown, Plus, Trash2, RotateCcw, History, X, DollarSign, MessageSquare, Calendar } from 'lucide-react';
|
import { Tag, TrendingDown, Plus, Trash2, RotateCcw, History, X, DollarSign, MessageSquare, Calendar } from 'lucide-react';
|
||||||
import { CategoryWithRemaining } from '../../services';
|
import type { CategoryWithRemaining } from '../../services';
|
||||||
import { categoryService, expenseService } from '../../services';
|
import { categoryService, expenseService } from '../../services';
|
||||||
import { useExpenses } from '../../hooks';
|
import { useExpenses } from '../../hooks';
|
||||||
import { format } from '../../utils/format';
|
import { format } from '../../utils/format';
|
||||||
import { Button, Input, Badge } from '../ui';
|
import { Button, Input } from '../ui';
|
||||||
|
|
||||||
interface CategoryCardProps {
|
interface CategoryCardProps {
|
||||||
category: CategoryWithRemaining;
|
category: CategoryWithRemaining;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { CategoryWithRemaining } from '../../services';
|
import type { CategoryWithRemaining } from '../../services';
|
||||||
import { CategoryCard } from './CategoryCard';
|
import { CategoryCard } from './CategoryCard';
|
||||||
|
|
||||||
interface CategoryListProps {
|
interface CategoryListProps {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Wallet, ShoppingCart } from 'lucide-react';
|
import { Wallet, ShoppingCart } from 'lucide-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { CategoryWithRemaining } from '../../services';
|
import type { CategoryWithRemaining } from '../../services';
|
||||||
import { format } from '../../utils/format';
|
import { format } from '../../utils/format';
|
||||||
|
|
||||||
interface FamilySummaryProps {
|
interface FamilySummaryProps {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { Copy, Check, Loader2 } from 'lucide-react';
|
import { Copy, Check, Loader2 } from 'lucide-react';
|
||||||
import { Modal, Button } from '../ui';
|
import { Modal, Button } from '../ui';
|
||||||
import { useInviteLink } from '../../hooks';
|
import { useInviteLink } from '../../hooks';
|
||||||
import { InviteLinkResponse } from '../../types';
|
import type { InviteLinkResponse } from '../../types';
|
||||||
|
|
||||||
interface InviteModalProps {
|
interface InviteModalProps {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Users, Edit3, Save, X, AlertTriangle, Loader2 } from 'lucide-react';
|
import { Users, Edit3, Save, X, AlertTriangle, Loader2 } from 'lucide-react';
|
||||||
import { Family } from '../../types';
|
import type { Family } from '../../types';
|
||||||
import { Card, Button, Input } from '../ui';
|
import { Card, Button, Input } from '../ui';
|
||||||
import { familyService } from '../../services';
|
import { familyService } from '../../services';
|
||||||
import { showToast } from '../../utils/toast';
|
import { showToast } from '../../utils/toast';
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Loader2 } from 'lucide-react';
|
import type { FamilyMember, User } from '../../types';
|
||||||
import { FamilyMember, User } from '../../types';
|
|
||||||
import { Badge, LoadingSpinner } from '../ui';
|
import { Badge, LoadingSpinner } from '../ui';
|
||||||
|
|
||||||
interface MembersSectionProps {
|
interface MembersSectionProps {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Settings, Palette, Languages } from 'lucide-react';
|
import { Settings, Palette, Languages } from 'lucide-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Theme } from '../../types';
|
import type { Theme } from '../../types';
|
||||||
import { Card } from '../ui';
|
import { Card } from '../ui';
|
||||||
import { ThemeSelector } from './ThemeSelector';
|
import { ThemeSelector } from './ThemeSelector';
|
||||||
import { LanguageSelector } from './LanguageSelector';
|
import { LanguageSelector } from './LanguageSelector';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Check } from 'lucide-react';
|
import { Check } from 'lucide-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Theme } from '../../types';
|
import type { Theme } from '../../types';
|
||||||
import { THEMES } from '../../constants';
|
import { THEMES } from '../../constants';
|
||||||
|
|
||||||
interface ThemeSelectorProps {
|
interface ThemeSelectorProps {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { User as UserIcon, LogOut } from 'lucide-react';
|
import { User as UserIcon, LogOut } from 'lucide-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { User } from '../../types';
|
import type { User } from '../../types';
|
||||||
import { Button, Card } from '../ui';
|
import { Button, Card } from '../ui';
|
||||||
|
|
||||||
interface UserInfoProps {
|
interface UserInfoProps {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { Trash2, Check, Pencil, X } from 'lucide-react';
|
import { Trash2, Check, Pencil, X } from 'lucide-react';
|
||||||
import { ShoppingItem } from '../../types';
|
import type { ShoppingItem } from '../../types';
|
||||||
import { Button, Input } from '../ui';
|
import { Button, Input } from '../ui';
|
||||||
|
|
||||||
interface ShoppingItemCardProps {
|
interface ShoppingItemCardProps {
|
||||||
@@ -12,7 +11,6 @@ interface ShoppingItemCardProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ShoppingItemCard({ item, onToggle, onDelete, onUpdate }: ShoppingItemCardProps) {
|
export function ShoppingItemCard({ item, onToggle, onDelete, onUpdate }: ShoppingItemCardProps) {
|
||||||
const { t } = useTranslation();
|
|
||||||
const [isEditing, setIsEditing] = useState(false);
|
const [isEditing, setIsEditing] = useState(false);
|
||||||
const [editName, setEditName] = useState(item.name);
|
const [editName, setEditName] = useState(item.name);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useState, KeyboardEvent } from 'react';
|
import { useState } from 'react';
|
||||||
|
import type { KeyboardEvent } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Plus } from 'lucide-react';
|
import { Plus } from 'lucide-react';
|
||||||
import { Button, Input } from '../ui';
|
import { Button, Input } from '../ui';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ShoppingItem } from '../../types';
|
import type { ShoppingItem } from '../../types';
|
||||||
import { ShoppingItemCard } from './ShoppingItemCard';
|
import { ShoppingItemCard } from './ShoppingItemCard';
|
||||||
import { shoppingService } from '../../services';
|
import { shoppingService } from '../../services';
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
interface BadgeProps {
|
interface BadgeProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ButtonHTMLAttributes, ReactNode } from 'react';
|
import type { ButtonHTMLAttributes, ReactNode } from 'react';
|
||||||
|
|
||||||
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
variant?: 'primary' | 'success' | 'danger' | 'secondary' | 'ghost';
|
variant?: 'primary' | 'success' | 'danger' | 'secondary' | 'ghost';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
interface CardProps {
|
interface CardProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { InputHTMLAttributes, forwardRef } from 'react';
|
import { forwardRef } from 'react';
|
||||||
|
import type { InputHTMLAttributes } from 'react';
|
||||||
|
|
||||||
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
||||||
label?: string;
|
label?: string;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ReactNode, useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
interface ModalProps {
|
interface ModalProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Theme } from '../types';
|
import type { Theme } from '../types';
|
||||||
|
|
||||||
export const THEMES: { id: Theme; gradient: string; name: string }[] = [
|
export const THEMES: { id: Theme; gradient: string; name: string }[] = [
|
||||||
{ id: 'light', gradient: 'bg-gradient-to-r from-gray-100 to-gray-200', name: 'Light' },
|
{ id: 'light', gradient: 'bg-gradient-to-r from-gray-100 to-gray-200', name: 'Light' },
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { categoryService, CategoryWithRemaining } from '../services';
|
import { categoryService } from '../services';
|
||||||
import { CreateCategoryRequest } from '../types';
|
import type { CategoryWithRemaining } from '../services';
|
||||||
|
import type { CreateCategoryRequest } from '../types';
|
||||||
import { showToast } from '../utils/toast';
|
import { showToast } from '../utils/toast';
|
||||||
import { showErrorToast } from '../utils/errorHandler';
|
import { showErrorToast } from '../utils/errorHandler';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { expenseService } from '../services';
|
import { expenseService } from '../services';
|
||||||
import { Expense, CreateExpenseRequest } from '../types';
|
import type { Expense, CreateExpenseRequest } from '../types';
|
||||||
import { showToast } from '../utils/toast';
|
import { showToast } from '../utils/toast';
|
||||||
import { showErrorToast } from '../utils/errorHandler';
|
import { showErrorToast } from '../utils/errorHandler';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { familyService } from '../services';
|
import { familyService } from '../services';
|
||||||
import { FamilyMember } from '../types';
|
import type { FamilyMember } from '../types';
|
||||||
import { showErrorToast } from '../utils/errorHandler';
|
import { showErrorToast } from '../utils/errorHandler';
|
||||||
|
|
||||||
export function useFamilyMembers(familyId: number | null) {
|
export function useFamilyMembers(familyId: number | null) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { inviteService } from '../services';
|
import { inviteService } from '../services';
|
||||||
import { InviteLinkResponse, CreateInviteLinkRequest } from '../types';
|
import type { InviteLinkResponse, CreateInviteLinkRequest } from '../types';
|
||||||
import { showToast } from '../utils/toast';
|
import { showToast } from '../utils/toast';
|
||||||
import { showErrorToast } from '../utils/errorHandler';
|
import { showErrorToast } from '../utils/errorHandler';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { shoppingService } from '../services';
|
import { shoppingService } from '../services';
|
||||||
import { ShoppingItem, CreateShoppingItemRequest } from '../types';
|
import type { ShoppingItem, CreateShoppingItemRequest } from '../types';
|
||||||
import { showToast } from '../utils/toast';
|
import { showToast } from '../utils/toast';
|
||||||
import { showErrorToast } from '../utils/errorHandler';
|
import { showErrorToast } from '../utils/errorHandler';
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ import { User as UserIcon } from 'lucide-react';
|
|||||||
import { familyApi, authApi } from '../api/client';
|
import { familyApi, authApi } from '../api/client';
|
||||||
import { useStore } from '../store/useStore';
|
import { useStore } from '../store/useStore';
|
||||||
import { useFamilyMembers, useConfirm } from '../hooks';
|
import { useFamilyMembers, useConfirm } from '../hooks';
|
||||||
import { Theme } from '../types';
|
import type { Theme } from '../types';
|
||||||
import { ProfileHeader } from '../components/profile/ProfileHeader';
|
import { ProfileHeader } from '../components/profile/ProfileHeader';
|
||||||
import { UserInfo } from '../components/profile/UserInfo';
|
|
||||||
import { FamilySection } from '../components/profile/FamilySection';
|
import { FamilySection } from '../components/profile/FamilySection';
|
||||||
import { MembersSection } from '../components/profile/MembersSection';
|
import { MembersSection } from '../components/profile/MembersSection';
|
||||||
import { SettingsSection } from '../components/profile/SettingsSection';
|
import { SettingsSection } from '../components/profile/SettingsSection';
|
||||||
@@ -19,7 +18,7 @@ export default function Profile() {
|
|||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { user, selectedFamily, setSelectedFamily, setUser, preferences, setPreferences } = useStore();
|
const { user, selectedFamily, setSelectedFamily, setUser, preferences, setPreferences } = useStore();
|
||||||
const { members, loading: membersLoading, loadMembers } = useFamilyMembers(user?.family_id || null);
|
const { members, loading: membersLoading } = useFamilyMembers(user?.family_id || null);
|
||||||
const { confirmState, confirm, cancel } = useConfirm();
|
const { confirmState, confirm, cancel } = useConfirm();
|
||||||
|
|
||||||
const [leavingFamily, setLeavingFamily] = useState(false);
|
const [leavingFamily, setLeavingFamily] = useState(false);
|
||||||
@@ -61,17 +60,6 @@ export default function Profile() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLogout = async () => {
|
|
||||||
try {
|
|
||||||
await authApi.logout();
|
|
||||||
setUser(null);
|
|
||||||
setSelectedFamily(null);
|
|
||||||
navigate('/login');
|
|
||||||
} catch (error) {
|
|
||||||
showErrorToast(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleThemeChange = (theme: Theme) => {
|
const handleThemeChange = (theme: Theme) => {
|
||||||
setPreferences({ ...preferences, theme });
|
setPreferences({ ...preferences, theme });
|
||||||
showToast.success(t('profile.themeChanged'));
|
showToast.success(t('profile.themeChanged'));
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { categoryApi, expenseApi } from '../api/client';
|
import { categoryApi, expenseApi } from '../api/client';
|
||||||
import { Category, CreateCategoryRequest, RemainingLimit } from '../types';
|
import type { Category, CreateCategoryRequest } from '../types';
|
||||||
import { handleApiError } from '../utils/errorHandler';
|
import { handleApiError } from '../utils/errorHandler';
|
||||||
|
|
||||||
export interface CategoryWithRemaining extends Category {
|
export interface CategoryWithRemaining extends Category {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { expenseApi } from '../api/client';
|
import { expenseApi } from '../api/client';
|
||||||
import { Expense, CreateExpenseRequest } from '../types';
|
import type { Expense, CreateExpenseRequest } from '../types';
|
||||||
import { handleApiError } from '../utils/errorHandler';
|
import { handleApiError } from '../utils/errorHandler';
|
||||||
|
|
||||||
export const expenseService = {
|
export const expenseService = {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { familyApi } from '../api/client';
|
import { familyApi } from '../api/client';
|
||||||
import { Family, CreateFamilyRequest, CreateMyFamilyRequest, CreateMyFamilyResponse, VerifyFamilyPasswordRequest, FamilyMember } from '../types';
|
import type { Family, CreateFamilyRequest, CreateMyFamilyRequest, CreateMyFamilyResponse, VerifyFamilyPasswordRequest, FamilyMember } from '../types';
|
||||||
import { handleApiError } from '../utils/errorHandler';
|
import { handleApiError } from '../utils/errorHandler';
|
||||||
|
|
||||||
export const familyService = {
|
export const familyService = {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { inviteLinkApi } from '../api/client';
|
import { inviteLinkApi } from '../api/client';
|
||||||
import { CreateInviteLinkRequest, InviteLinkResponse, ValidateInviteResponse, JoinFamilyResponse } from '../types';
|
import type { CreateInviteLinkRequest, InviteLinkResponse, ValidateInviteResponse, JoinFamilyResponse } from '../types';
|
||||||
import { handleApiError } from '../utils/errorHandler';
|
import { handleApiError } from '../utils/errorHandler';
|
||||||
|
|
||||||
export const inviteService = {
|
export const inviteService = {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { shoppingItemApi } from '../api/client';
|
import { shoppingItemApi } from '../api/client';
|
||||||
import { ShoppingItem, CreateShoppingItemRequest, UpdateShoppingItemRequest, MarkAsPurchasedRequest } from '../types';
|
import type { ShoppingItem, CreateShoppingItemRequest, UpdateShoppingItemRequest, MarkAsPurchasedRequest } from '../types';
|
||||||
import { handleApiError } from '../utils/errorHandler';
|
import { handleApiError } from '../utils/errorHandler';
|
||||||
|
|
||||||
export const shoppingService = {
|
export const shoppingService = {
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export const useStore = create<AppState>((set, get) => ({
|
|||||||
},
|
},
|
||||||
|
|
||||||
clearCache: () => {
|
clearCache: () => {
|
||||||
set((state) => ({
|
set(() => ({
|
||||||
cache: {
|
cache: {
|
||||||
categories: new Map(),
|
categories: new Map(),
|
||||||
members: new Map(),
|
members: new Map(),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { ApiError, AppError } from '../types/errors';
|
import { AppError } from '../types/errors';
|
||||||
import { showToast } from './toast';
|
import { showToast } from './toast';
|
||||||
|
|
||||||
export function handleApiError(error: unknown): never {
|
export function handleApiError(error: unknown): never {
|
||||||
|
|||||||
Reference in New Issue
Block a user