diff --git a/frontend/components/EmptyState.js b/frontend/components/EmptyState.js
deleted file mode 100644
index 0153da4..0000000
--- a/frontend/components/EmptyState.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Icon } from './icons';
-
-export default function EmptyState({
- icon = 'info',
- title = '暂无数据',
- description = '这里还没有内容',
- action,
- actionLabel,
- onAction,
-}) {
- return (
-
-
-
{title}
- {description &&
{description}
}
- {action && (
-
- )}
-
- );
-}
diff --git a/frontend/components/PageTransition.js b/frontend/components/PageTransition.js
deleted file mode 100644
index e5daa37..0000000
--- a/frontend/components/PageTransition.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import { useEffect, useState } from 'react';
-import { useRouter } from 'next/router';
-
-export default function PageTransition({ children }) {
- const router = useRouter();
- const [isAnimating, setIsAnimating] = useState(false);
- const [displayChildren, setDisplayChildren] = useState(children);
-
- useEffect(() => {
- const handleRouteChangeStart = () => {
- setIsAnimating(true);
- };
-
- const handleRouteChangeComplete = () => {
- setDisplayChildren(children);
- setTimeout(() => {
- setIsAnimating(false);
- }, 50);
- };
-
- router.events.on('routeChangeStart', handleRouteChangeStart);
- router.events.on('routeChangeComplete', handleRouteChangeComplete);
-
- return () => {
- router.events.off('routeChangeStart', handleRouteChangeStart);
- router.events.off('routeChangeComplete', handleRouteChangeComplete);
- };
- }, [router, children]);
-
- useEffect(() => {
- if (!isAnimating) {
- setDisplayChildren(children);
- }
- }, [children, isAnimating]);
-
- return (
-
- {displayChildren}
-
- );
-}
diff --git a/frontend/components/SwipeableItem.js b/frontend/components/SwipeableItem.js
deleted file mode 100644
index eed4897..0000000
--- a/frontend/components/SwipeableItem.js
+++ /dev/null
@@ -1,93 +0,0 @@
-import { useState, useRef, useCallback } from 'react';
-
-export default function SwipeableItem({
- children,
- onSwipeLeft,
- renderRightActions,
- swipeThreshold = 80,
-}) {
- const [isSwiping, setIsSwiping] = useState(false);
- const [translateX, setTranslateX] = useState(0);
- const [isRevealed, setIsRevealed] = useState(false);
- const startXRef = useRef(0);
- const currentXRef = useRef(0);
- const itemRef = useRef(null);
-
- const handleTouchStart = useCallback((e) => {
- startXRef.current = e.touches[0].clientX;
- currentXRef.current = startXRef.current;
- setIsSwiping(true);
- }, []);
-
- const handleTouchMove = useCallback((e) => {
- if (!isSwiping) return;
-
- currentXRef.current = e.touches[0].clientX;
- const diff = currentXRef.current - startXRef.current;
-
- // Only allow swiping left (negative diff)
- if (diff < 0) {
- // Limit the swipe distance
- const newTranslateX = Math.max(diff, -swipeThreshold - 20);
- setTranslateX(newTranslateX);
- } else if (isRevealed) {
- // If already revealed, allow swiping right to close
- const newTranslateX = Math.min(0, -swipeThreshold + diff);
- setTranslateX(newTranslateX);
- }
- }, [isSwiping, isRevealed, swipeThreshold]);
-
- const handleTouchEnd = useCallback(() => {
- setIsSwiping(false);
- const diff = currentXRef.current - startXRef.current;
-
- if (diff < -swipeThreshold / 2 || (isRevealed && diff > -swipeThreshold / 2)) {
- // Reveal actions
- setTranslateX(-swipeThreshold);
- setIsRevealed(true);
- } else {
- // Snap back
- setTranslateX(0);
- setIsRevealed(false);
- }
- }, [isRevealed, swipeThreshold]);
-
- const handleClose = useCallback(() => {
- setTranslateX(0);
- setIsRevealed(false);
- }, []);
-
- const handleActionClick = useCallback((callback) => {
- callback?.();
- handleClose();
- }, [handleClose]);
-
- return (
-
-
- {children}
-
- {renderRightActions && (
-
- {renderRightActions(handleActionClick)}
-
- )}
-
- );
-}
diff --git a/frontend/pages/_app.js b/frontend/pages/_app.js
index 9046097..798f429 100644
--- a/frontend/pages/_app.js
+++ b/frontend/pages/_app.js
@@ -2,7 +2,6 @@ import { SWRConfig } from 'swr';
import ErrorBoundary from '../components/ErrorBoundary';
import { ToastProvider } from '../components/ToastProvider';
import { ConfirmProvider } from '../components/ConfirmProvider';
-import PageTransition from '../components/PageTransition';
import { swrConfig } from '../lib/swr-config';
import '../styles/globals.css';
@@ -12,9 +11,7 @@ export default function App({ Component, pageProps }) {
-
-
-
+
diff --git a/frontend/pages/index.js b/frontend/pages/index.js
index 6e1de03..8d4da8f 100644
--- a/frontend/pages/index.js
+++ b/frontend/pages/index.js
@@ -4,12 +4,10 @@ import { isLoggedIn, getRecords, getStats, createRecord, updateRecord, deleteRec
import AppShell from '../components/AppShell';
import { Icon } from '../components/icons';
import RecordModal from '../components/RecordModal';
-import SwipeableItem from '../components/SwipeableItem';
-import EmptyState from '../components/EmptyState';
import { useToast } from '../components/ToastProvider';
import { useConfirm } from '../components/ConfirmProvider';
import { useCategories } from '../hooks/useCategories';
-import { getMonthStr, formatMoney, formatMonth, parseDateTime } from '../lib/utils';
+import { getMonthStr, formatMoney, formatMonth, parseDateTime, getDatePart } from '../lib/utils';
export default function Home() {
const router = useRouter();
@@ -193,23 +191,6 @@ export default function Home() {
}
};
- const handleQuickDelete = async (record) => {
- const shouldDelete = await confirm({
- title: '删除这条记录?',
- description: `${record.category} ${record.type === 'income' ? '+' : '-'}${formatMoney(record.amount)}`,
- confirmText: '删除',
- });
- if (!shouldDelete) return;
-
- try {
- await deleteRecord(record.id);
- setRecords(prev => prev.filter(r => r.id !== record.id));
- showToast('记录已删除', { tone: 'success' });
- } catch (err) {
- showToast(err.message, { tone: 'error' });
- }
- };
-
const groupedRecords = useMemo(() => {
return records.reduce((groups, record) => {
const date = getDatePart(record.date);
@@ -305,14 +286,10 @@ export default function Home() {
{loading ? (
加载中...
) : records.length === 0 ? (
-
+
) : (
{sortedDates.map((date) => (
@@ -324,44 +301,19 @@ export default function Home() {
{groupedRecords[date].map((record) => {
const icon = categoryIconMap[`${record.type}:${record.category}`] || '📝';
return (
-
openEditModal(record)}
- renderRightActions={(handleAction) => (
- <>
-
-
- >
- )}
- >
-