Implement quick title suggestions
Implement suggestions for transaction titles based on category selection.
This commit is contained in:
@@ -6,6 +6,8 @@ import { Input } from '@/components/ui/input';
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Loader2 } from 'lucide-react';
|
import { Loader2 } from 'lucide-react';
|
||||||
import ExpenseCategorySelector from './ExpenseCategorySelector';
|
import ExpenseCategorySelector from './ExpenseCategorySelector';
|
||||||
|
import { CATEGORY_TITLE_SUGGESTIONS } from '@/constants/categoryIcons';
|
||||||
|
import { Badge } from '@/components/ui/badge';
|
||||||
|
|
||||||
export interface ExpenseFormValues {
|
export interface ExpenseFormValues {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -28,6 +30,17 @@ const ExpenseForm: React.FC<ExpenseFormProps> = ({ onSubmit, onCancel, isSubmitt
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 현재 선택된 카테고리 가져오기
|
||||||
|
const selectedCategory = form.watch('category');
|
||||||
|
|
||||||
|
// 선택된 카테고리에 대한 제목 제안 목록 가져오기
|
||||||
|
const titleSuggestions = selectedCategory ? CATEGORY_TITLE_SUGGESTIONS[selectedCategory] : [];
|
||||||
|
|
||||||
|
// 제안된 제목 클릭 시 제목 필드에 설정
|
||||||
|
const handleTitleSuggestionClick = (suggestion: string) => {
|
||||||
|
form.setValue('title', suggestion);
|
||||||
|
};
|
||||||
|
|
||||||
// Format number with commas
|
// Format number with commas
|
||||||
const formatWithCommas = (value: string): string => {
|
const formatWithCommas = (value: string): string => {
|
||||||
// Remove commas first to avoid duplicates when typing
|
// Remove commas first to avoid duplicates when typing
|
||||||
@@ -58,6 +71,24 @@ const ExpenseForm: React.FC<ExpenseFormProps> = ({ onSubmit, onCancel, isSubmitt
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* 카테고리별 제목 제안 */}
|
||||||
|
{titleSuggestions.length > 0 && (
|
||||||
|
<div className="mt-1 mb-2">
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{titleSuggestions.map((suggestion) => (
|
||||||
|
<Badge
|
||||||
|
key={suggestion}
|
||||||
|
variant="outline"
|
||||||
|
className="cursor-pointer hover:bg-neuro-income/10 transition-colors px-3 py-1"
|
||||||
|
onClick={() => handleTitleSuggestionClick(suggestion)}
|
||||||
|
>
|
||||||
|
{suggestion}
|
||||||
|
</Badge>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* 제목 필드를 두 번째로 배치 */}
|
{/* 제목 필드를 두 번째로 배치 */}
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { FormField, FormItem, FormLabel, FormControl, FormMessage } from '@/components/ui/form';
|
import { FormField, FormItem, FormLabel, FormControl, FormMessage } from '@/components/ui/form';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { UseFormReturn } from 'react-hook-form';
|
import { UseFormReturn } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { categoryIcons, EXPENSE_CATEGORIES } from '@/constants/categoryIcons';
|
import { categoryIcons, EXPENSE_CATEGORIES, CATEGORY_TITLE_SUGGESTIONS } from '@/constants/categoryIcons';
|
||||||
|
import { Badge } from '@/components/ui/badge';
|
||||||
|
|
||||||
// Form schema for validation - 카테고리를 4개로 확장
|
// Form schema for validation - 카테고리를 4개로 확장
|
||||||
export const transactionFormSchema = z.object({
|
export const transactionFormSchema = z.object({
|
||||||
@@ -31,6 +32,17 @@ const TransactionFormFields: React.FC<TransactionFormFieldsProps> = ({ form }) =
|
|||||||
form.setValue('amount', formattedValue);
|
form.setValue('amount', formattedValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 현재 선택된 카테고리 가져오기
|
||||||
|
const selectedCategory = form.watch('category');
|
||||||
|
|
||||||
|
// 선택된 카테고리에 대한 제목 제안 목록 가져오기
|
||||||
|
const titleSuggestions = selectedCategory ? CATEGORY_TITLE_SUGGESTIONS[selectedCategory] : [];
|
||||||
|
|
||||||
|
// 제안된 제목 클릭 시 제목 필드에 설정
|
||||||
|
const handleTitleSuggestionClick = (suggestion: string) => {
|
||||||
|
form.setValue('title', suggestion);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* 카테고리 필드를 첫 번째로 배치 */}
|
{/* 카테고리 필드를 첫 번째로 배치 */}
|
||||||
@@ -63,6 +75,24 @@ const TransactionFormFields: React.FC<TransactionFormFieldsProps> = ({ form }) =
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* 카테고리별 제목 제안 */}
|
||||||
|
{titleSuggestions.length > 0 && (
|
||||||
|
<div className="mt-1 mb-3">
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{titleSuggestions.map((suggestion) => (
|
||||||
|
<Badge
|
||||||
|
key={suggestion}
|
||||||
|
variant="outline"
|
||||||
|
className="cursor-pointer hover:bg-neuro-income/10 transition-colors px-3 py-1"
|
||||||
|
onClick={() => handleTitleSuggestionClick(suggestion)}
|
||||||
|
>
|
||||||
|
{suggestion}
|
||||||
|
</Badge>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* 제목 필드를 두 번째로 배치 */}
|
{/* 제목 필드를 두 번째로 배치 */}
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|||||||
@@ -35,3 +35,11 @@ export const DEFAULT_CATEGORY_BUDGETS = {
|
|||||||
|
|
||||||
// 기본 월간 예산
|
// 기본 월간 예산
|
||||||
export const DEFAULT_MONTHLY_BUDGET = 1300000;
|
export const DEFAULT_MONTHLY_BUDGET = 1300000;
|
||||||
|
|
||||||
|
// 카테고리별 대표 제목 목록 정의
|
||||||
|
export const CATEGORY_TITLE_SUGGESTIONS: Record<string, string[]> = {
|
||||||
|
음식: ['점심', '저녁', '음료', '간식', '아침', '외식'],
|
||||||
|
쇼핑: ['의류', '생활용품', '운동용품', '가전제품', '화장품'],
|
||||||
|
교통: ['택시', '주유', '버스', '지하철', '교통카드', '주차'],
|
||||||
|
기타: ['구독', '관리비', '전기요금', '통신비', '의료비', '취미']
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user