This commit is contained in:
aaron 2026-04-27 23:20:38 +08:00
parent cf695efb38
commit c34f257fd0
2 changed files with 52 additions and 36 deletions

View File

@ -28,20 +28,12 @@ import {
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { toast } from "sonner";
export function Header() {
const { user, logout } = useAuth();
const router = useRouter();
const { activeClassId, activeClassName, canSwitchClass, availableClasses, setActiveClassId } =
useActiveClass();
const { activeClassName } = useActiveClass();
const { toggle } = useSidebar();
const { unreadCount, notifications, markRead, markAllRead, refresh } = useNotifications();
const [notifOpen, setNotifOpen] = useState(false);
@ -52,9 +44,7 @@ export function Header() {
const [newPassword, setNewPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [passwordLoading, setPasswordLoading] = useState(false);
const classDescriptor = activeClassName
? activeClassName.split(" ").slice(0, 2).join(" ")
: "香港大学中国商业学院";
const classDescriptor = activeClassName || "香港大学中国商业学院";
const handleChangePassword = async (e: React.FormEvent) => {
e.preventDefault();
@ -99,32 +89,11 @@ export function Header() {
<p className="text-[11px] uppercase tracking-[0.24em] text-[#94613e]">
HKU ICB
</p>
<h2 className="truncate text-lg font-semibold text-[#4a1f1a]">
<h2 className="text-lg font-semibold text-[#4a1f1a]">
{classDescriptor}
</h2>
</div>
{canSwitchClass ? (
<Select
value={activeClassId ? String(activeClassId) : ""}
onValueChange={(v) => v && setActiveClassId(parseInt(v))}
>
<SelectTrigger className="w-56 border-[#d7c0a0] bg-white/75 shadow-none">
<SelectValue>
{activeClassId
? availableClasses.find((c) => c.id === activeClassId)?.name ||
"选择班级"
: "选择班级"}
</SelectValue>
</SelectTrigger>
<SelectContent>
{availableClasses.map((c) => (
<SelectItem key={c.id} value={String(c.id)}>
{c.name} ({c.cohort_year})
</SelectItem>
))}
</SelectContent>
</Select>
) : activeClassName ? (
{activeClassName ? (
<span className="text-sm text-[#6f4b38] md:hidden">
<span className="font-medium text-[#4a1f1a]">{activeClassName}</span>
</span>

View File

@ -8,6 +8,13 @@ import { cn } from "@/lib/utils";
import type { ClassPermission, UserRole } from "@/lib/types";
import { useAuth } from "@/hooks/use-auth";
import { hasClassPermission } from "@/lib/permissions";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
const navItems = [
{ href: "/dashboard", label: "首页", icon: "M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6", moduleKey: undefined },
@ -32,7 +39,14 @@ export function Sidebar() {
const pathname = usePathname();
const { isOpen, close } = useSidebar();
const { user } = useAuth();
const { enabledModules, activeClassId } = useActiveClass();
const {
enabledModules,
activeClassId,
activeClassName,
canSwitchClass,
availableClasses,
setActiveClassId,
} = useActiveClass();
const visibleAdminItems = user
? adminItems.filter((item) => {
if (!item.roles.includes(user.role)) return false;
@ -75,6 +89,39 @@ export function Sidebar() {
<div className="border-b border-sidebar-border px-6 pb-6 pt-7">
<h1 className="text-2xl font-semibold tracking-tight text-white"></h1>
<p className="mt-1 text-sm text-white/65">HKU ICB</p>
{activeClassName && (
<div className="mt-5 rounded-2xl border border-white/10 bg-white/[0.06] p-4">
<p className="text-[11px] uppercase tracking-[0.22em] text-white/38">
</p>
<p className="mt-2 text-sm font-medium leading-6 text-white">
{activeClassName}
</p>
{canSwitchClass && availableClasses.length > 1 && (
<div className="mt-3">
<Select
value={activeClassId ? String(activeClassId) : ""}
onValueChange={(value) => value && setActiveClassId(Number(value))}
>
<SelectTrigger className="h-auto w-full rounded-xl border-white/12 bg-white/8 px-3 py-2 text-left text-sm text-white hover:bg-white/12">
<SelectValue>
{activeClassId
? availableClasses.find((item) => item.id === activeClassId)?.name ?? "切换班级"
: "切换班级"}
</SelectValue>
</SelectTrigger>
<SelectContent className="border-[#e2ccb0] bg-[#fffaf2]">
{availableClasses.map((item) => (
<SelectItem key={item.id} value={String(item.id)}>
{item.name} ({item.cohort_year})
</SelectItem>
))}
</SelectContent>
</Select>
</div>
)}
</div>
)}
</div>
<nav className="flex-1 space-y-1 overflow-y-auto px-4 py-5">