From 44cf749bc91db86f1b4023acc90ecbfd586e04e5 Mon Sep 17 00:00:00 2001 From: Martin Berka Date: Sun, 8 Mar 2026 09:59:07 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20nov=C3=BD=20zp=C5=AFsob=20zobrazov?= =?UTF-8?q?=C3=A1n=C3=AD=20novinek?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: oprava kopírování changelogů do Docker image fix: oprava kopírování changelogů do Docker image fix: oprava --- Dockerfile | 7 ++- Dockerfile-Woodpecker | 8 +++- client/src/components/Header.tsx | 56 ++++++++++++++++++------ server/changelogs/2025-01-07.json | 4 ++ server/changelogs/2025-01-15.json | 3 ++ server/changelogs/2025-01-29.json | 3 ++ server/changelogs/2025-02-19.json | 3 ++ server/changelogs/2025-02-27.json | 3 ++ server/changelogs/2025-03-05.json | 3 ++ server/changelogs/2025-03-20.json | 3 ++ server/changelogs/2025-03-21.json | 3 ++ server/changelogs/2025-08-01.json | 3 ++ server/changelogs/2025-10-06.json | 3 ++ server/changelogs/2025-10-11.json | 4 ++ server/changelogs/2025-11-03.json | 3 ++ server/changelogs/2026-01-09.json | 3 ++ server/changelogs/2026-01-13.json | 3 ++ server/changelogs/2026-01-30.json | 3 ++ server/changelogs/2026-02-04.json | 7 +++ server/changelogs/2026-02-10.json | 3 ++ server/changelogs/2026-02-20.json | 3 ++ server/changelogs/2026-03-04.json | 3 ++ server/changelogs/2026-03-05.json | 3 ++ server/changelogs/2026-03-08.json | 3 ++ server/src/index.ts | 2 + server/src/routes/changelogRoutes.ts | 50 +++++++++++++++++++++ types/api.yml | 4 ++ types/paths/changelogs/getChangelogs.yml | 21 +++++++++ 28 files changed, 199 insertions(+), 18 deletions(-) create mode 100644 server/changelogs/2025-01-07.json create mode 100644 server/changelogs/2025-01-15.json create mode 100644 server/changelogs/2025-01-29.json create mode 100644 server/changelogs/2025-02-19.json create mode 100644 server/changelogs/2025-02-27.json create mode 100644 server/changelogs/2025-03-05.json create mode 100644 server/changelogs/2025-03-20.json create mode 100644 server/changelogs/2025-03-21.json create mode 100644 server/changelogs/2025-08-01.json create mode 100644 server/changelogs/2025-10-06.json create mode 100644 server/changelogs/2025-10-11.json create mode 100644 server/changelogs/2025-11-03.json create mode 100644 server/changelogs/2026-01-09.json create mode 100644 server/changelogs/2026-01-13.json create mode 100644 server/changelogs/2026-01-30.json create mode 100644 server/changelogs/2026-02-04.json create mode 100644 server/changelogs/2026-02-10.json create mode 100644 server/changelogs/2026-02-20.json create mode 100644 server/changelogs/2026-03-04.json create mode 100644 server/changelogs/2026-03-05.json create mode 100644 server/changelogs/2026-03-08.json create mode 100644 server/src/routes/changelogRoutes.ts create mode 100644 types/paths/changelogs/getChangelogs.yml diff --git a/Dockerfile b/Dockerfile index 67bfdc1..e940d6c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -82,8 +82,11 @@ COPY --from=builder /build/client/dist ./public # Zkopírování produkčních .env serveru COPY /server/.env.production ./server -# Zkopírování konfigurace easter eggů -RUN if [ -f /server/.easter-eggs.json ]; then cp /server/.easter-eggs.json ./server/; fi +# Zkopírování changelogů (seznamu novinek) +COPY /server/changelogs ./server/changelogs + +# Zkopírování konfigurace easter eggů a changelogů +RUN if [ -f ./server/.easter-eggs.json ]; then cp ./server/.easter-eggs.json ./server/; fi # Export /data/db.json do složky /data VOLUME ["/data"] diff --git a/Dockerfile-Woodpecker b/Dockerfile-Woodpecker index 6291b32..3dc9ec2 100644 --- a/Dockerfile-Woodpecker +++ b/Dockerfile-Woodpecker @@ -18,8 +18,12 @@ COPY ./server/dist ./ # Vykopírování sestaveného klienta COPY ./client/dist ./public -# Zkopírování konfigurace easter eggů -RUN if [ -f ./server/.easter-eggs.json ]; then cp ./server/.easter-eggs.json ./server/; fi +# Zkopírování changelogů (seznamu novinek) +COPY ./server/changelogs ./server/changelogs + +# Zkopírování konfigurace easter eggů a changelogů +RUN if [ -f ./server/.easter-eggs.json ]; then cp ./server/.easter-eggs.json ./server/; fi \ + && if [ -d ./server/changelogs ]; then cp -r ./server/changelogs ./server/changelogs; fi EXPOSE 3000 diff --git a/client/src/components/Header.tsx b/client/src/components/Header.tsx index 0af7f47..9b279c6 100644 --- a/client/src/components/Header.tsx +++ b/client/src/components/Header.tsx @@ -11,16 +11,12 @@ import GenerateMockDataModal from "./modals/GenerateMockDataModal"; import ClearMockDataModal from "./modals/ClearMockDataModal"; import { useNavigate } from "react-router"; import { STATS_URL } from "../AppRoutes"; -import { FeatureRequest, getVotes, updateVote, LunchChoices } from "../../../types"; +import { FeatureRequest, getVotes, updateVote, LunchChoices, getChangelogs } from "../../../types"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faSun, faMoon } from "@fortawesome/free-solid-svg-icons"; +import { formatDateString } from "../Utils"; -const CHANGELOG = [ - "Nový moderní design aplikace", - "Oprava parsování Sladovnické a TechTower", - "Možnost označit se jako objednávající u volby \"budu objednávat\"", - "Možnost generovat QR kódy pro platby (i mimo Pizza day)", -]; +const LAST_SEEN_CHANGELOG_KEY = "lastChangelogDate"; const IS_DEV = process.env.NODE_ENV === 'development'; @@ -38,6 +34,7 @@ export default function Header({ choices, dayIndex }: Props) { const [pizzaModalOpen, setPizzaModalOpen] = useState(false); const [refreshMenuModalOpen, setRefreshMenuModalOpen] = useState(false); const [changelogModalOpen, setChangelogModalOpen] = useState(false); + const [changelogEntries, setChangelogEntries] = useState>({}); const [qrModalOpen, setQrModalOpen] = useState(false); const [generateMockModalOpen, setGenerateMockModalOpen] = useState(false); const [clearMockModalOpen, setClearMockModalOpen] = useState(false); @@ -71,6 +68,19 @@ export default function Header({ choices, dayIndex }: Props) { } }, [auth?.login]); + useEffect(() => { + if (!auth?.login) return; + const lastSeen = localStorage.getItem(LAST_SEEN_CHANGELOG_KEY) ?? undefined; + getChangelogs({ query: lastSeen ? { since: lastSeen } : {} }).then(response => { + const entries = response.data; + if (!entries || Object.keys(entries).length === 0) return; + setChangelogEntries(entries); + setChangelogModalOpen(true); + const newestDate = Object.keys(entries).sort((a, b) => b.localeCompare(a))[0]; + localStorage.setItem(LAST_SEEN_CHANGELOG_KEY, newestDate); + }); + }, [auth?.login]); + const closeSettingsModal = () => { setSettingsModalOpen(false); } @@ -197,7 +207,17 @@ export default function Header({ choices, dayIndex }: Props) { setPizzaModalOpen(true)}>Pizza kalkulačka Generování QR kódů navigate(STATS_URL)}>Statistiky - setChangelogModalOpen(true)}>Novinky + { + getChangelogs().then(response => { + const entries = response.data ?? {}; + setChangelogEntries(entries); + setChangelogModalOpen(true); + const dates = Object.keys(entries).sort((a, b) => b.localeCompare(a)); + if (dates.length > 0) { + localStorage.setItem(LAST_SEEN_CHANGELOG_KEY, dates[0]); + } + }); + }}>Novinky {IS_DEV && ( <> @@ -237,16 +257,24 @@ export default function Header({ choices, dayIndex }: Props) { /> )} - setChangelogModalOpen(false)}> + setChangelogModalOpen(false)} size="lg">

Novinky

-
    - {CHANGELOG.map((item, index) => ( -
  • {item}
  • - ))} -
+ {Object.keys(changelogEntries).sort((a, b) => b.localeCompare(a)).map(date => ( +
+ {formatDateString(date)} +
    + {changelogEntries[date].map((item, index) => ( +
  • {item}
  • + ))} +
+
+ ))} + {Object.keys(changelogEntries).length === 0 && ( +

Žádné novinky.

+ )}