diff --git a/.github/workflows/test-app.yml b/.github/workflows/test-app.yml index 0a9e073f..34822054 100644 --- a/.github/workflows/test-app.yml +++ b/.github/workflows/test-app.yml @@ -59,5 +59,15 @@ jobs: - name: Install dependencies run: npm ci + - name: Cache Next.js build + uses: actions/cache@v4 + with: + path: .next/cache + key: nextjs-${{ hashFiles('package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx', '**/*.css') }} + restore-keys: nextjs-${{ hashFiles('package-lock.json') }}- + + - name: Disable Next.js telemetry + run: npx next telemetry disable + - name: Build run: npm run build diff --git a/pages/404.tsx b/pages/404.tsx index c8af0613..c063b5ab 100644 --- a/pages/404.tsx +++ b/pages/404.tsx @@ -1,7 +1,8 @@ import type { NextPage } from "next" import { Wrapper } from "@/components/Wrapper" import { NotFound } from "@/components/NotFound" -import Copyright from "@/components/Copyright" +import { Copyright } from "@/components/Copyright" +import { yearRange } from "@/const" import { Spacer } from "@/components/Spacer" import { Box } from "@/ui/Box" @@ -11,7 +12,7 @@ const Index: NextPage = () => ( footer={( - + )} diff --git a/pages/_app.tsx b/pages/_app.tsx index 4554ee69..23ec58e3 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -4,56 +4,52 @@ import "src/style/article.css" import "src/style/marker/marker-table.css" import "src/style/kazimir/video.css" -import App from "next/app" +import type { AppProps } from "next/app" import Head from "next/head" import Script from "next/script" import { YMetrika } from "@/components/YMetrika" import { ThemeColor } from "@/ui/ThemeColor" -export default class MyApp extends App { - render() { - const { Component, pageProps } = this.props +export default function MyApp({ Component, pageProps }: AppProps) { + return ( + <> + + + + - return ( - <> - - - - + + + + + + - - - - - - + + + + + - - - - - + - + {process.env.NEXT_PUBLIC_YMETRIKA_ACCOUNT && ( + + )} - {process.env.NEXT_PUBLIC_YMETRIKA_ACCOUNT && ( - - )} + + + - - - - - - - ) - } + + + ) } diff --git a/src/components/App/app.module.css b/src/components/App/app.module.css new file mode 100644 index 00000000..98e7f20b --- /dev/null +++ b/src/components/App/app.module.css @@ -0,0 +1,18 @@ +.navigation { + padding: var(--size-s); +} + +.footerLinks { + margin-bottom: var(--size-l); +} + +.footerPanel { + align-items: baseline; +} + +.gosuslugi { + background-color: white; + padding: 10px; + border-radius: 10px; + margin-bottom: 30px; +} diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 98f6c121..e3843644 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -1,3 +1,5 @@ +import s from "./app.module.css" + import { Wrapper } from "../Wrapper" import { MenuContext } from "@/context/MenuContext" import { Footer } from "../Footer" @@ -9,7 +11,8 @@ import { useMobile } from "@/hooks/useMobile" import { Navigation } from "@/components/Navigation" import { Box } from "@/ui/Box" import { AccessibilityButton } from "../AccessibilityButton" -import Copyright from "@/components/Copyright" +import { Copyright } from "@/components/Copyright" +import { yearRange } from "@/const" import { Spacer } from "../Spacer" import { Author } from "../Author" import { Title } from "@/ui/Title" @@ -18,7 +21,6 @@ import { Contacts } from "../Contacts" import dynamic from "next/dynamic" import Link from "next/link" -import Image from "next/image" import AccessibilityPanel from "../AccessibilityPanel" import useAccessibility from "@/hooks/useAccessibility" @@ -34,13 +36,10 @@ export type AppProps = { children?: React.ReactNode } -export const App: React.FC = ({ showAuthor = false, menu, ...props }) => { +export function App({ showAuthor = false, menu, ...props }: AppProps) { const hideBreadcrumbs = useMobile() const accessibility = useAccessibility() const router = useRouter() - const blockStyle = { - justifyContent: "center", - } return ( @@ -51,11 +50,11 @@ export const App: React.FC = ({ showAuthor = false, menu, ...props }) )} - +
+ +
{hideBreadcrumbs || !props.breadcrumbs ? null : ( - + = ({ showAuthor = false, menu, ...props }) )} footer={(
- + - + Версия для слабовидящих - + Анкеты @@ -113,17 +106,12 @@ export const App: React.FC = ({ showAuthor = false, menu, ...props }) -
+
- + {!showAuthor ? null : ( <> @@ -135,7 +123,7 @@ export const App: React.FC = ({ showAuthor = false, menu, ...props })
)} > - + {props.children} diff --git a/src/components/Copyright/index.tsx b/src/components/Copyright/index.tsx index 4df84aeb..c7133dc2 100644 --- a/src/components/Copyright/index.tsx +++ b/src/components/Copyright/index.tsx @@ -1,13 +1,9 @@ -import { state } from "@/store/config" -import { useSnapshot } from "valtio" - -function Copyright() { - const { years } = useSnapshot(state) - const year = years.map(String).join("—") - - return ( - © {year} Шлиссельбургская детская художественная школа - ) +export type CopyrightProps = { + years: string } -export default Copyright +export function Copyright({ years }: CopyrightProps) { + return ( + © {years} Шлиссельбургская детская художественная школа + ) +} diff --git a/src/const.ts b/src/const.ts new file mode 100644 index 00000000..26b737e5 --- /dev/null +++ b/src/const.ts @@ -0,0 +1 @@ +export const yearRange = [2012, 2026].join("—") diff --git a/src/store/config.ts b/src/store/config.ts index 3a73aa90..d87a65ab 100644 --- a/src/store/config.ts +++ b/src/store/config.ts @@ -1,7 +1,5 @@ import { proxy } from "valtio" -const currentYear = () => (new Date()).getFullYear() - type Contact = { type: string value: string @@ -9,12 +7,10 @@ type Contact = { } type State = { - years: [number, number] contacts: Contact[] } export const state = proxy({ - years: [2012, currentYear()], contacts: [ { type: "link", diff --git a/src/ui/Panel/Panel.test.tsx b/src/ui/Panel/Panel.test.tsx index d0c9829f..a1ef4cd4 100644 --- a/src/ui/Panel/Panel.test.tsx +++ b/src/ui/Panel/Panel.test.tsx @@ -20,4 +20,10 @@ describe("Panel", () => { expect(el.className).toMatch(/ghost/) expect(el.className).not.toMatch(/default/) }) + + it("forwards a custom className", () => { + const { container } = render(content) + const el = container.firstElementChild! + expect(el.className).toContain("custom") + }) }) diff --git a/src/ui/Panel/index.tsx b/src/ui/Panel/index.tsx index 4f4d901b..8615ccda 100644 --- a/src/ui/Panel/index.tsx +++ b/src/ui/Panel/index.tsx @@ -5,18 +5,20 @@ import { Box } from "../Box" export type PanelProps = { children?: React.ReactNode style?: React.CSSProperties + className?: string ghost?: boolean } -export const Panel: React.FC = ({ +export function Panel({ style, + className, children, ghost = false, -}) => { +}: PanelProps) { const variant = ghost ? s.ghost : s.default return ( - + {children} )