diff --git a/src/components/StudentManager.tsx b/src/components/StudentManager.tsx index 404d712..18f10b9 100644 --- a/src/components/StudentManager.tsx +++ b/src/components/StudentManager.tsx @@ -54,6 +54,8 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { const [form] = Form.useForm() const [groupForm] = Form.useForm() const [messageApi, contextHolder] = message.useMessage() + const addFormGroupName = Form.useWatch("group_name", form) + const editFormGroupName = Form.useWatch("group_name", groupForm) const isMobile = useIsMobile() const isTablet = useIsTablet() const breakpoint = useResponsive() @@ -666,6 +668,22 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { return baseColumns }, [t, canEdit, isMobile, isTablet, breakpoint]) + const existingGroupNames = useMemo(() => { + const groups = new Set() + data.forEach((student) => { + const normalized = student.group_name?.trim() + if (normalized) groups.add(normalized) + }) + return Array.from(groups).sort((a, b) => a.localeCompare(b, "zh-CN")) + }, [data]) + + const normalizedAddFormGroupName = + typeof addFormGroupName === "string" && addFormGroupName.trim() ? addFormGroupName.trim() : "" + const normalizedEditFormGroupName = + typeof editFormGroupName === "string" && editFormGroupName.trim() + ? editFormGroupName.trim() + : "" + const paginatedData = data.slice((currentPage - 1) * pageSize, currentPage * pageSize) return ( @@ -725,6 +743,32 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { +
+
+ {t("students.existingGroups")} +
+ {existingGroupNames.length > 0 ? ( + + {existingGroupNames.map((group) => { + const active = normalizedAddFormGroupName === group + return ( + form.setFieldValue("group_name", group)} + > + {group} + + ) + })} + + ) : ( +
+ {t("students.noExistingGroups")} +
+ )} +
@@ -746,6 +790,32 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { +
+
+ {t("students.existingGroups")} +
+ {existingGroupNames.length > 0 ? ( + + {existingGroupNames.map((group) => { + const active = normalizedEditFormGroupName === group + return ( + groupForm.setFieldValue("group_name", group)} + > + {group} + + ) + })} + + ) : ( +
+ {t("students.noExistingGroups")} +
+ )} +
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 1005c6a..87ec0a8 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -488,6 +488,8 @@ "editGroupTitle": "Set Group - {{name}}", "groupSaveSuccess": "Group saved", "groupSaveFailed": "Failed to save group", + "existingGroups": "Existing groups (click to fill)", + "noExistingGroups": "No existing groups yet", "noGroup": "Ungrouped", "editAvatarTitle": "Set Avatar - {{name}}", "avatarUpload": "Upload Image", diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index fed10ec..a4e039f 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -488,6 +488,8 @@ "editGroupTitle": "设置小组 - {{name}}", "groupSaveSuccess": "小组保存成功", "groupSaveFailed": "小组保存失败", + "existingGroups": "已有小组(点击一键填入)", + "noExistingGroups": "暂无可用的小组", "noGroup": "未分组", "editAvatarTitle": "设置头像 - {{name}}", "avatarUpload": "上传图片",