feat: fetch menu items from cms

This commit is contained in:
Zotov Ivan Yuryevich
2026-04-16 22:41:30 +03:00
parent 173708addb
commit 3d985584fe
9 changed files with 82 additions and 62 deletions

View File

@@ -1,12 +1,14 @@
import { Send, Video } from 'lucide-react'
import { SiteContactItems } from '../components/SiteContactItems'
import type { CategoriesListQuery } from '../graphql/graphql'
import type { MenuItemsQuery } from '../graphql/graphql'
import type { SiteConfigContact } from '../lib/cms/contact/types'
type CategoryNavItem = NonNullable<MenuItemsQuery['categories'][number]>
export interface FooterProps {
contacts: readonly SiteConfigContact[]
solutionCategories: ReadonlyArray<NonNullable<CategoriesListQuery['categories'][number]>>
solutionCategories: CategoryNavItem[]
}
export function Footer({ contacts, solutionCategories }: FooterProps) {
@@ -62,7 +64,7 @@ export function Footer({ contacts, solutionCategories }: FooterProps) {
<h4 className="text-white mb-6">Решения</h4>
<ul className="space-y-3">
{solutionCategories.map(category => (
<li key={category.documentId}>
<li key={category.slug}>
<a href={`/${category.slug}`} className="hover:text-blue-400 transition-colors">
{category.title ?? category.slug}
</a>

View File

@@ -1,27 +1,24 @@
import { Menu, X, ChevronDown } from 'lucide-react'
import { useState } from 'react'
import { ContactModal } from '../components/ContactModal'
import type { CategoriesListQuery } from '../graphql/graphql'
import type { MenuItemsQuery } from '../graphql/graphql'
import type { SiteConfigContact } from '../lib/cms/contact/types'
import { navigateHomeSectionAnchor } from '../lib/scrollToHash'
type CategoryNavItem = NonNullable<CategoriesListQuery['categories'][number]>
type CategoryNavItem = NonNullable<MenuItemsQuery['categories'][number]>
export interface HeaderProps {
contacts: readonly SiteConfigContact[]
solutionCategories: readonly CategoryNavItem[]
serviceCategories: readonly CategoryNavItem[]
solutions: readonly CategoryNavItem[]
services: readonly CategoryNavItem[]
}
export function Header({ contacts, solutionCategories, serviceCategories }: HeaderProps) {
export function Header({ contacts, solutions, services }: HeaderProps) {
const [isMenuOpen, setIsMenuOpen] = useState(false)
const [isSolutionsOpen, setIsSolutionsOpen] = useState(false)
const [isServicesOpen, setIsServicesOpen] = useState(false)
const [isContactModalOpen, setIsContactModalOpen] = useState(false)
const solutions = [...solutionCategories].sort((a, b) => a.sortOrder - b.sortOrder)
const services = [...serviceCategories].sort((a, b) => a.sortOrder - b.sortOrder)
return (
<header className="fixed top-0 left-0 right-0 z-50 bg-white/80 backdrop-blur-md border-b border-gray-100">
<nav className="max-w-400 mx-auto px-6 xl:px-12 2xl:px-16 py-4">
@@ -48,7 +45,7 @@ export function Header({ contacts, solutionCategories, serviceCategories }: Head
<div className="w-80 bg-white rounded-xl shadow-xl border border-gray-100 py-3 animate-in fade-in slide-in-from-top-2 duration-200">
{solutions.map(solution => (
<a
key={solution.documentId}
key={solution.slug}
href={`/${solution.slug}`}
className="block w-full text-left px-5 py-3 text-gray-700 hover:bg-blue-50 hover:text-blue-600 transition-colors"
>
@@ -76,7 +73,7 @@ export function Header({ contacts, solutionCategories, serviceCategories }: Head
<div className="w-80 bg-white rounded-xl shadow-xl border border-gray-100 py-3 animate-in fade-in slide-in-from-top-2 duration-200">
{services.map(service => (
<a
key={service.documentId}
key={service.slug}
href={`/${service.slug}`}
className="block w-full text-left px-5 py-3 text-gray-700 hover:bg-blue-50 hover:text-blue-600 transition-colors"
>
@@ -143,7 +140,7 @@ export function Header({ contacts, solutionCategories, serviceCategories }: Head
<div className="pl-4 mt-2 space-y-2">
{solutions.map(solution => (
<a
key={solution.documentId}
key={solution.slug}
href={`/${solution.slug}`}
onClick={() => {
setIsMenuOpen(false)
@@ -172,7 +169,7 @@ export function Header({ contacts, solutionCategories, serviceCategories }: Head
<div className="pl-4 mt-2 space-y-2">
{services.map(service => (
<a
key={service.documentId}
key={service.slug}
href={`/${service.slug}`}
onClick={() => {
setIsMenuOpen(false)
@@ -221,11 +218,7 @@ export function Header({ contacts, solutionCategories, serviceCategories }: Head
</div>
)}
</nav>
<ContactModal
isOpen={isContactModalOpen}
onClose={() => setIsContactModalOpen(false)}
contacts={contacts}
/>
<ContactModal isOpen={isContactModalOpen} onClose={() => setIsContactModalOpen(false)} contacts={contacts} />
</header>
)
}