5 changed files with 212 additions and 7 deletions
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"recommendations": [ |
||||
|
"bradlc.vscode-tailwindcss", |
||||
|
"ms-vscode.vscode-typescript-next", |
||||
|
"esbenp.prettier-vscode", |
||||
|
"ms-vscode.vscode-eslint" |
||||
|
] |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
{ |
||||
|
"tailwindCSS.includeLanguages": { |
||||
|
"typescript": "html", |
||||
|
"typescriptreact": "html", |
||||
|
"javascript": "html", |
||||
|
"javascriptreact": "html" |
||||
|
}, |
||||
|
"tailwindCSS.experimental.classRegex": [ |
||||
|
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], |
||||
|
["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"], |
||||
|
["cn\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"] |
||||
|
], |
||||
|
"tailwindCSS.validate": true, |
||||
|
"tailwindCSS.lint.cssConflict": "warning", |
||||
|
"tailwindCSS.lint.invalidApply": "error", |
||||
|
"tailwindCSS.lint.invalidConfigPath": "error", |
||||
|
"tailwindCSS.lint.invalidScreen": "error", |
||||
|
"tailwindCSS.lint.invalidTailwindDirective": "error", |
||||
|
"tailwindCSS.lint.invalidVariant": "error", |
||||
|
"tailwindCSS.lint.recommendedVariantOrder": "warning", |
||||
|
"editor.quickSuggestions": { |
||||
|
"strings": true |
||||
|
}, |
||||
|
"css.validate": false, |
||||
|
"scss.validate": false |
||||
|
} |
@ -0,0 +1,165 @@ |
|||||
|
'use client'; |
||||
|
import { useState, useEffect } from 'react'; |
||||
|
import Link from 'next/link'; |
||||
|
import { usePathname } from 'next/navigation'; |
||||
|
import {getSiteInfo} from "@/api/layout"; |
||||
|
import {CmsWebsite} from "@/api/cms/cmsWebsite/model"; |
||||
|
|
||||
|
|
||||
|
const Header = () => { |
||||
|
const [config, setConfig] = useState<CmsWebsite>({}) |
||||
|
const [isMenuOpen, setIsMenuOpen] = useState(false); |
||||
|
const pathname = usePathname(); |
||||
|
|
||||
|
const navigation = [ |
||||
|
{ name: '首页', href: '/' }, |
||||
|
{ name: '产品', href: '/products' }, |
||||
|
{ name: '解决方案', href: '/solutions' }, |
||||
|
{ name: '案例', href: '/cases' }, |
||||
|
{ name: '关于', href: '/about' }, |
||||
|
{ name: '联系', href: '/contact' }, |
||||
|
]; |
||||
|
|
||||
|
const isActive = (href: string) => { |
||||
|
if (href === '/') { |
||||
|
return pathname === '/'; |
||||
|
} |
||||
|
return pathname.startsWith(href); |
||||
|
}; |
||||
|
|
||||
|
const reload = () => { |
||||
|
getSiteInfo().then(data => { |
||||
|
console.log(data,'data') |
||||
|
if(data){ |
||||
|
setConfig(data); |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
useEffect(() => { |
||||
|
reload(); |
||||
|
}, []); |
||||
|
|
||||
|
return ( |
||||
|
<header className="bg-white shadow-sm border-b border-gray-100 sticky top-0 z-50"> |
||||
|
<div className="container mx-auto px-4"> |
||||
|
<div className="flex items-center justify-between h-16"> |
||||
|
{/* Logo */} |
||||
|
<div className="flex-shrink-0"> |
||||
|
<Link href="/" className="text-xl font-bold text-gray-800"> |
||||
|
= {config?.websiteName} = |
||||
|
</Link> |
||||
|
</div> |
||||
|
|
||||
|
{/* Desktop Navigation */} |
||||
|
<nav className="hidden md:block"> |
||||
|
<div className="flex items-center space-x-8"> |
||||
|
{navigation.map((item) => ( |
||||
|
<Link |
||||
|
key={item.name} |
||||
|
href={item.href} |
||||
|
className={`text-sm font-medium transition-colors duration-300 ${ |
||||
|
isActive(item.href) |
||||
|
? 'text-blue-600' |
||||
|
: 'text-gray-700 hover:text-blue-600' |
||||
|
}`}
|
||||
|
> |
||||
|
{item.name} |
||||
|
</Link> |
||||
|
))} |
||||
|
</div> |
||||
|
</nav> |
||||
|
|
||||
|
{/* Language Switch & CTA */} |
||||
|
<div className="hidden md:flex items-center space-x-4"> |
||||
|
<div className="flex items-center space-x-2 text-sm text-gray-600"> |
||||
|
<span className="cursor-pointer hover:text-blue-600">中文</span> |
||||
|
<span>|</span> |
||||
|
<span className="cursor-pointer hover:text-blue-600">EN</span> |
||||
|
</div> |
||||
|
<Link href="/contact" className="btn btn-primary text-sm"> |
||||
|
免费咨询 |
||||
|
</Link> |
||||
|
</div> |
||||
|
|
||||
|
{/* Mobile menu button */} |
||||
|
<div className="md:hidden"> |
||||
|
<button |
||||
|
onClick={() => setIsMenuOpen(!isMenuOpen)} |
||||
|
className="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue-500" |
||||
|
aria-expanded="false" |
||||
|
> |
||||
|
<span className="sr-only">打开主菜单</span> |
||||
|
{!isMenuOpen ? ( |
||||
|
<svg |
||||
|
className="block h-6 w-6" |
||||
|
xmlns="http://www.w3.org/2000/svg" |
||||
|
fill="none" |
||||
|
viewBox="0 0 24 24" |
||||
|
stroke="currentColor" |
||||
|
aria-hidden="true" |
||||
|
> |
||||
|
<path |
||||
|
strokeLinecap="round" |
||||
|
strokeLinejoin="round" |
||||
|
strokeWidth={2} |
||||
|
d="M4 6h16M4 12h16M4 18h16" |
||||
|
/> |
||||
|
</svg> |
||||
|
) : ( |
||||
|
<svg |
||||
|
className="block h-6 w-6" |
||||
|
xmlns="http://www.w3.org/2000/svg" |
||||
|
fill="none" |
||||
|
viewBox="0 0 24 24" |
||||
|
stroke="currentColor" |
||||
|
aria-hidden="true" |
||||
|
> |
||||
|
<path |
||||
|
strokeLinecap="round" |
||||
|
strokeLinejoin="round" |
||||
|
strokeWidth={2} |
||||
|
d="M6 18L18 6M6 6l12 12" |
||||
|
/> |
||||
|
</svg> |
||||
|
)} |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
{/* Mobile Navigation */} |
||||
|
{isMenuOpen && ( |
||||
|
<div className="md:hidden"> |
||||
|
<div className="px-2 pt-2 pb-3 space-y-1 sm:px-3 bg-white border-t border-gray-200"> |
||||
|
{navigation.map((item) => ( |
||||
|
<Link |
||||
|
key={item.name} |
||||
|
href={item.href} |
||||
|
className={`block px-3 py-2 rounded-md text-base font-medium transition-colors duration-300 ${ |
||||
|
isActive(item.href) |
||||
|
? 'text-blue-600 bg-blue-50' |
||||
|
: 'text-gray-700 hover:text-blue-600 hover:bg-gray-50' |
||||
|
}`}
|
||||
|
onClick={() => setIsMenuOpen(false)} |
||||
|
> |
||||
|
{item.name} |
||||
|
</Link> |
||||
|
))} |
||||
|
<div className="px-3 py-2"> |
||||
|
<Link |
||||
|
href="/contact" |
||||
|
className="btn btn-primary w-full" |
||||
|
onClick={() => setIsMenuOpen(false)} |
||||
|
> |
||||
|
免费咨询 |
||||
|
</Link> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
)} |
||||
|
</div> |
||||
|
</header> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
export default Header; |
@ -0,0 +1,12 @@ |
|||||
|
/** @type {import('tailwindcss').Config} */ |
||||
|
module.exports = { |
||||
|
content: [ |
||||
|
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}', |
||||
|
'./src/components/**/*.{js,ts,jsx,tsx,mdx}', |
||||
|
'./src/app/**/*.{js,ts,jsx,tsx,mdx}', |
||||
|
], |
||||
|
theme: { |
||||
|
extend: {}, |
||||
|
}, |
||||
|
plugins: [], |
||||
|
} |
Loading…
Reference in new issue