feat: UI optimizations - button feedback, layout fixes, cache clearing, work/exam records

- Add active: state feedback to all buttons across the app
- Fix cache clearing to update Zustand store (not just localStorage)
- Remove checkboxes from settings cache section, compact layout
- Settings page: single outer scroll instead of dual-column scroll
- CourseWorkspace: elastic log panel height, work/exam record counts
- Integrate WorkList/ExamList types and display in UI
- Delete unused CourseList.tsx component
- Fix wk.ts: strict equality, remove unused import

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 17:36:02 +08:00
parent 13f0be162b
commit a1911573d1
13 changed files with 603 additions and 302 deletions

View File

@@ -1,5 +1,6 @@
import { createStore } from "zustand/vanilla";
import { createJSONStorage, persist } from "zustand/middleware";
import { accountStore } from "~/store/account";
export type HostOption = {
label: string;
@@ -37,6 +38,7 @@ type SettingsState = {
};
const accountStorageKey = "account-storage";
const settingsStorageKey = "settings-storage";
type PersistedStorage = {
state?: Record<string, unknown>;
version?: number;
@@ -115,53 +117,40 @@ export const settingsStore = createStore<SettingsState>()(
}
},
clearPersistedSection: (section) => {
const store = accountStore.getState();
if (section === "accounts") {
patchAccountStorage((state) => {
const {
accounts,
selectedAccountId,
expandedAccountId,
selectedCourseId,
records,
recordCacheMap,
studyLogsMap,
runningStudyMap,
...rest
} = state;
void accounts;
void selectedAccountId;
void expandedAccountId;
void selectedCourseId;
void records;
void recordCacheMap;
void studyLogsMap;
void runningStudyMap;
return rest;
});
store.clearAccountsData();
localStorage.removeItem(accountStorageKey);
}
if (section === "records") {
store.clearRecordsData();
patchAccountStorage((state) => {
const { records, recordCacheMap, selectedCourseId, ...rest } =
state;
const { records, recordCacheMap, workList, examList, workExamCacheMap, ...rest } = state;
void records;
void recordCacheMap;
void selectedCourseId;
void workList;
void examList;
void workExamCacheMap;
return rest;
});
}
if (section === "logs") {
store.clearAllStudyLogs();
patchAccountStorage((state) => {
const { studyLogsMap, runningStudyMap, ...rest } = state;
const { studyLogsMap, ...rest } = state;
void studyLogsMap;
void runningStudyMap;
return rest;
});
}
},
clearAllPersistedData: () => {
accountStore.getState().clearAllData();
localStorage.removeItem(accountStorageKey);
localStorage.removeItem(settingsStorageKey);
window.location.reload();
},
setDebugEnabled: (value) => set({ debugEnabled: value }),
setAutoScrollLogs: (value) => set({ autoScrollLogs: value }),