mirror of
https://github.com/iflytek/skillhub.git
synced 2026-10-10 03:27:54 +00:00
Merge pull request #16 from iflytek/fix/v7-migration-jsonb-type
feat: add explore link to navbar and fix logout/migration issues
This commit is contained in:
commit
8194e821f8
5 changed files with 38 additions and 21 deletions
|
|
@ -1,12 +1,10 @@
|
|||
-- Fix audit_log detail_json column to properly handle JSONB type
|
||||
-- This migration ensures existing data is compatible with the JSONB type
|
||||
|
||||
-- The column is already defined as jsonb in V1, but we need to ensure
|
||||
-- any existing string data can be properly cast to jsonb
|
||||
ALTER TABLE audit_log
|
||||
ALTER COLUMN detail_json TYPE jsonb
|
||||
USING CASE
|
||||
WHEN detail_json IS NULL THEN NULL
|
||||
WHEN detail_json = '' THEN NULL
|
||||
ELSE detail_json::jsonb
|
||||
END;
|
||||
-- The column is already defined as jsonb in V1, so this migration is a no-op
|
||||
-- for fresh installations. For existing installations with text data, this would
|
||||
-- have been needed, but since the column was always jsonb, we just verify it exists.
|
||||
|
||||
-- No-op migration: column is already jsonb in V1
|
||||
-- This file exists to maintain migration version continuity
|
||||
SELECT 1;
|
||||
|
|
|
|||
|
|
@ -25,15 +25,31 @@ export function Layout() {
|
|||
{/* Glass header */}
|
||||
<header className="sticky top-0 z-50 glass-strong border-b border-border/40">
|
||||
<div className="container mx-auto flex h-16 items-center justify-between px-4 lg:px-8">
|
||||
<Link to="/" className="flex items-center gap-2 group">
|
||||
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-primary to-primary/70 flex items-center justify-center shadow-glow">
|
||||
<span className="text-primary-foreground font-bold text-sm">S</span>
|
||||
</div>
|
||||
<span className="text-xl font-bold font-heading text-foreground group-hover:text-primary transition-colors">
|
||||
SkillHub
|
||||
</span>
|
||||
</Link>
|
||||
{/* 左侧: Logo + 主导航 */}
|
||||
<div className="flex items-center gap-8">
|
||||
<Link to="/" className="flex items-center gap-2 group">
|
||||
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-primary to-primary/70 flex items-center justify-center shadow-glow">
|
||||
<span className="text-primary-foreground font-bold text-sm">S</span>
|
||||
</div>
|
||||
<span className="text-xl font-bold font-heading text-foreground group-hover:text-primary transition-colors">
|
||||
SkillHub
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
{/* 主导航链接 */}
|
||||
<nav className="hidden md:flex items-center gap-6">
|
||||
<Link
|
||||
to="/search"
|
||||
search={{ q: '', sort: 'relevance', page: 0 }}
|
||||
className="text-sm font-medium text-muted-foreground hover:text-foreground transition-colors"
|
||||
activeProps={{ className: 'text-primary' }}
|
||||
>
|
||||
{t('nav.explore')}
|
||||
</Link>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{/* 右侧菜单 */}
|
||||
<nav className="flex items-center gap-6">
|
||||
<LanguageSwitcher />
|
||||
{isLoading ? null : user ? (
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"nav": {
|
||||
"home": "Home",
|
||||
"explore": "Explore Skills",
|
||||
"search": "Search Skills",
|
||||
"dashboard": "Dashboard",
|
||||
"login": "Login"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"nav": {
|
||||
"home": "首页",
|
||||
"explore": "探索",
|
||||
"search": "搜索技能",
|
||||
"dashboard": "控制台",
|
||||
"login": "登录"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { Link, useNavigate } from '@tanstack/react-router'
|
||||
import { Link } from '@tanstack/react-router'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import { authApi } from '@/api/client'
|
||||
import {
|
||||
|
|
@ -22,7 +22,6 @@ interface UserMenuProps {
|
|||
|
||||
export function UserMenu({ user }: UserMenuProps) {
|
||||
const { t } = useTranslation()
|
||||
const navigate = useNavigate()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const hasRole = (role: string) => user.platformRoles?.includes(role) ?? false
|
||||
|
|
@ -34,10 +33,12 @@ export function UserMenu({ user }: UserMenuProps) {
|
|||
const handleLogout = async () => {
|
||||
try {
|
||||
await authApi.logout()
|
||||
queryClient.setQueryData(['auth', 'me'], null)
|
||||
navigate({ to: '/' })
|
||||
} catch (error) {
|
||||
console.error('Logout failed:', error)
|
||||
} finally {
|
||||
// Always clear cache and redirect, even if API call fails
|
||||
queryClient.setQueryData(['auth', 'me'], null)
|
||||
window.location.href = '/'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue