feat: add useCampus hook and CampusSwitcher component
This commit is contained in:
36
apps/admin/src/components/CampusSwitcher.tsx
Normal file
36
apps/admin/src/components/CampusSwitcher.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
import { Select, Typography } from 'antd';
|
||||
import { EnvironmentOutlined } from '@ant-design/icons';
|
||||
import { useCampus } from '../hooks/useCampus';
|
||||
|
||||
const CampusSwitcher: React.FC = () => {
|
||||
const { campuses, currentId, switchCampus, loading } = useCampus();
|
||||
|
||||
if (campuses.length <= 1) {
|
||||
return (
|
||||
<Typography.Text style={{ color: '#fff', marginRight: 24 }}>
|
||||
<EnvironmentOutlined style={{ marginRight: 4 }} />
|
||||
{campuses[0]?.name || '主校区'}
|
||||
</Typography.Text>
|
||||
);
|
||||
}
|
||||
|
||||
const options = [
|
||||
...campuses.map((c) => ({ value: String(c.id), label: c.name })),
|
||||
{ value: '', label: '全部校区' },
|
||||
];
|
||||
|
||||
return (
|
||||
<Select
|
||||
value={currentId || undefined}
|
||||
onChange={switchCampus}
|
||||
options={options}
|
||||
loading={loading}
|
||||
style={{ minWidth: 140, marginRight: 24 }}
|
||||
variant="borderless"
|
||||
popupMatchSelectWidth={false}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default CampusSwitcher;
|
||||
40
apps/admin/src/hooks/useCampus.ts
Normal file
40
apps/admin/src/hooks/useCampus.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import api from '../api';
|
||||
|
||||
interface Department {
|
||||
id: number;
|
||||
name: string;
|
||||
type: string;
|
||||
parentId: number | null;
|
||||
}
|
||||
|
||||
export function useCampus() {
|
||||
const [campuses, setCampuses] = useState<Department[]>([]);
|
||||
const [currentId, setCurrentId] = useState<string>(
|
||||
() => localStorage.getItem('currentCampusId') || ''
|
||||
);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const fetchCampuses = useCallback(async () => {
|
||||
try {
|
||||
const data = await api.get('/departments') as unknown as Department[];
|
||||
const campusList = data.filter((d) => d.type === 'campus');
|
||||
setCampuses(campusList);
|
||||
if (!currentId && campusList.length > 0) {
|
||||
setCurrentId(String(campusList[0].id));
|
||||
localStorage.setItem('currentCampusId', String(campusList[0].id));
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
finally { setLoading(false); }
|
||||
}, [currentId]);
|
||||
|
||||
useEffect(() => { fetchCampuses(); }, []);
|
||||
|
||||
const switchCampus = useCallback((id: string) => {
|
||||
setCurrentId(id);
|
||||
localStorage.setItem('currentCampusId', id);
|
||||
window.dispatchEvent(new CustomEvent('campus-changed', { detail: id }));
|
||||
}, []);
|
||||
|
||||
return { campuses, currentId, switchCampus, loading };
|
||||
}
|
||||
Reference in New Issue
Block a user