PublicLayout.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import React from 'react'
  2. import type { ReactNode } from 'react'
  3. import { Link, useLocation } from 'react-router-dom'
  4. import { useLegacyThemePage, usePageContext } from '../shared/pageContext'
  5. import { AppLogo } from '../components/common/AppLogo'
  6. function PublicHeader() {
  7. const { locale, path, copy } = usePageContext()
  8. const location = useLocation()
  9. const profilePath = path('/profile')
  10. const customerSimulationPath = path('/customer-simulation')
  11. const isCustomerSimulation = location.pathname.startsWith(customerSimulationPath)
  12. const pageCopy = copy.publicLayout
  13. const navCopy = locale === 'zh'
  14. ? { profile: '美发师主页', templates: '发型参考', simulation: 'AI发型试试看', reviews: '评价' }
  15. : pageCopy.nav
  16. return (
  17. <header>
  18. <nav className="navbar navbar-expand-lg header-light bg-white box-shadow-small">
  19. <div className="container-fluid">
  20. <div className="col-auto me-auto">
  21. <Link className="navbar-brand" to={path('')}>
  22. <AppLogo />
  23. </Link>
  24. </div>
  25. <div className="col-auto menu-order position-static">
  26. <button
  27. className="navbar-toggler float-start"
  28. type="button"
  29. data-bs-toggle="collapse"
  30. data-bs-target="#publicNavbarNav"
  31. aria-controls="publicNavbarNav"
  32. aria-label="Toggle navigation"
  33. >
  34. <span className="navbar-toggler-line"></span>
  35. <span className="navbar-toggler-line"></span>
  36. <span className="navbar-toggler-line"></span>
  37. <span className="navbar-toggler-line"></span>
  38. </button>
  39. <div className="collapse navbar-collapse" id="publicNavbarNav">
  40. <ul className="navbar-nav">
  41. <li className="nav-item"><a href={`${profilePath}#profile`} className="nav-link">{navCopy.profile}</a></li>
  42. <li className="nav-item"><a href={`${profilePath}#templates`} className="nav-link">{navCopy.templates}</a></li>
  43. <li className="nav-item"><Link to={customerSimulationPath} className={`nav-link${isCustomerSimulation ? ' active' : ''}`}>{navCopy.simulation}</Link></li>
  44. <li className="nav-item"><a href={`${profilePath}#reviews`} className="nav-link">{navCopy.reviews}</a></li>
  45. </ul>
  46. </div>
  47. </div>
  48. </div>
  49. </nav>
  50. </header>
  51. )
  52. }
  53. export function PublicLayout({ children, footer = true }: { children: ReactNode; footer?: boolean }) {
  54. useLegacyThemePage({ bodyClassName: '', mobileNavStyle: 'classic' })
  55. const { copy } = usePageContext()
  56. return (
  57. <>
  58. <PublicHeader />
  59. {children}
  60. {footer ? (
  61. <footer className="p-0 footer-light position-relative">
  62. <div className="container">
  63. <div className="row justify-content-center pt-5 pb-5 sm-pt-40px sm-pb-40px">
  64. <div className="col-12 text-center">
  65. <img src="/images/logo_color.svg" alt="Aitori Stylist" className="footer-logo mb-20px" style={{ maxWidth: '160px' }} />
  66. <div className="fs-16 text-medium-gray">{copy.publicLayout.footer}</div>
  67. </div>
  68. </div>
  69. </div>
  70. </footer>
  71. ) : null}
  72. </>
  73. )
  74. }