From 0f44fe74fbc5cd7c7b2341b50c29cb0f8bed3a6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Grutle?= Date: Tue, 19 Sep 2023 12:55:37 +0200 Subject: [PATCH] feat(date): show date last modified (#1198) * feat(date) show date last modified * feat(date) update last modified and created * feat(date) remove console logs * feat(date) rebase * feat(date) update last active time * feat(date) meta type with meta information * feat(date) ping to update last active date * feat(date) fix consistency * feat(date) change order of last active and created * feat(date) dynamic api routes and remove last active and created from my boards * feat(date) rebase master * fix(edit) delete debug logs * fix(edit) change from date strings to number * feat(date) move logic from hook * feat(date) remove some logic * feat(date) remove comment * feat(date) update lastActive field directly * feat(date) throw error if board does not exist --- next-tavla/pages/[id].tsx | 2 ++ next-tavla/pages/api/ping/[id].ts | 18 +++++++++++++ .../BoardList/components/Row/index.tsx | 7 ++++- .../components/Row/styles.module.css | 2 +- .../src/Admin/scenarios/BoardList/index.tsx | 6 ++--- next-tavla/src/Admin/scenarios/Edit/index.tsx | 2 +- .../src/Admin/scenarios/Edit/reducer.ts | 8 +++++- .../src/Admin/scenarios/TableHeader/index.tsx | 1 + .../scenarios/TableHeader/styles.module.css | 2 +- next-tavla/src/Admin/utils/firebase.ts | 26 +++++++++++++++++-- .../src/Shared/hooks/useUpdateLastActive.ts | 20 ++++++++++++++ next-tavla/src/Shared/types/meta.ts | 7 +++++ next-tavla/src/Shared/types/settings.ts | 4 +-- next-tavla/src/Shared/utils/time.ts | 12 +++++++++ 14 files changed, 105 insertions(+), 12 deletions(-) create mode 100644 next-tavla/pages/api/ping/[id].ts create mode 100644 next-tavla/src/Shared/hooks/useUpdateLastActive.ts create mode 100644 next-tavla/src/Shared/types/meta.ts diff --git a/next-tavla/pages/[id].tsx b/next-tavla/pages/[id].tsx index 4a2ace02b..7e5470a6a 100644 --- a/next-tavla/pages/[id].tsx +++ b/next-tavla/pages/[id].tsx @@ -4,6 +4,7 @@ import classes from 'styles/pages/board.module.css' import { upgradeBoard } from 'utils/converters' import { Board } from 'Board/scenarios/Board' import { getBoard } from 'Admin/utils/firebase' +import { useUpdateLastActive } from 'hooks/useUpdateLastActive' export async function getServerSideProps({ params, @@ -30,6 +31,7 @@ export async function getServerSideProps({ } function BoardPage({ board }: { board: TBoard }) { + useUpdateLastActive(board.id) return (
diff --git a/next-tavla/pages/api/ping/[id].ts b/next-tavla/pages/api/ping/[id].ts new file mode 100644 index 000000000..6e2c4ec37 --- /dev/null +++ b/next-tavla/pages/api/ping/[id].ts @@ -0,0 +1,18 @@ +import { initializeAdminApp, setLastActive } from 'Admin/utils/firebase' +import { NextApiRequest, NextApiResponse } from 'next' +import { TBoardID } from 'types/settings' + +initializeAdminApp() + +export default async function handler( + request: NextApiRequest, + response: NextApiResponse, +) { + const { id } = request.query + try { + await setLastActive(id as TBoardID) + return response.status(200).json({ message: 'Successfully updated!' }) + } catch (error) { + return response.status(400).json({ error: 'Could not update!' }) + } +} diff --git a/next-tavla/src/Admin/scenarios/BoardList/components/Row/index.tsx b/next-tavla/src/Admin/scenarios/BoardList/components/Row/index.tsx index 05e4cec6f..2a57cbd73 100644 --- a/next-tavla/src/Admin/scenarios/BoardList/components/Row/index.tsx +++ b/next-tavla/src/Admin/scenarios/BoardList/components/Row/index.tsx @@ -8,6 +8,7 @@ import { useEffect, useState } from 'react' import { Cell } from 'Admin/scenarios/BoardList/components/Cell' import { Tooltip } from '@entur/tooltip' import { Info } from 'Admin/scenarios/Info' +import { formatDate } from 'utils/time' function Row({ board }: { board: TBoard }) { const { addToast } = useToast() @@ -24,7 +25,7 @@ function Row({ board }: { board: TBoard }) { return (
- {board?.title ?? 'Tavla'} + {board?.meta?.title ?? 'Tavla'} {link} @@ -47,6 +48,10 @@ function Row({ board }: { board: TBoard }) { + + {board?.meta?.dateModified && + formatDate(new Date(board.meta.dateModified))} +
) } diff --git a/next-tavla/src/Admin/scenarios/BoardList/components/Row/styles.module.css b/next-tavla/src/Admin/scenarios/BoardList/components/Row/styles.module.css index ab8f2c1f8..7556e87c1 100644 --- a/next-tavla/src/Admin/scenarios/BoardList/components/Row/styles.module.css +++ b/next-tavla/src/Admin/scenarios/BoardList/components/Row/styles.module.css @@ -1,6 +1,6 @@ .tableRow { display: grid; - grid-template-columns: 3fr 5fr 1fr; + grid-template-columns: 3fr 5fr 2fr 2fr; padding: 1rem 0; border-bottom: var(--colors-blues-blue20) solid; } diff --git a/next-tavla/src/Admin/scenarios/BoardList/index.tsx b/next-tavla/src/Admin/scenarios/BoardList/index.tsx index 31b1f0215..987fa7db3 100644 --- a/next-tavla/src/Admin/scenarios/BoardList/index.tsx +++ b/next-tavla/src/Admin/scenarios/BoardList/index.tsx @@ -18,8 +18,8 @@ function BoardList({ boards }: { boards: TBoard[] }) { const [selectedSort, setSelectedSort] = useState(sortOptions[0]) const sortBoards = (boardA: TBoard, boardB: TBoard) => { - const titleA = boardA?.title?.toLowerCase() ?? '' - const titleB = boardB?.title?.toLowerCase() ?? '' + const titleA = boardA?.meta?.title?.toLowerCase() ?? '' + const titleB = boardB?.meta?.title?.toLowerCase() ?? '' if (!selectedSort) return 0 switch (selectedSort.value) { case 'alphabetical': @@ -66,7 +66,7 @@ function BoardList({ boards }: { boards: TBoard[] }) {
{boards .filter((board) => - textSearchRegex.test(board?.title ?? ''), + textSearchRegex.test(board?.meta?.title ?? ''), ) .sort(sortBoards) .map((board) => ( diff --git a/next-tavla/src/Admin/scenarios/Edit/index.tsx b/next-tavla/src/Admin/scenarios/Edit/index.tsx index b9d7dcf8c..b954ac863 100644 --- a/next-tavla/src/Admin/scenarios/Edit/index.tsx +++ b/next-tavla/src/Admin/scenarios/Edit/index.tsx @@ -33,7 +33,7 @@ function Edit({
- +
{ diff --git a/next-tavla/src/Admin/scenarios/Edit/reducer.ts b/next-tavla/src/Admin/scenarios/Edit/reducer.ts index 9901d6b74..663dfcab7 100644 --- a/next-tavla/src/Admin/scenarios/Edit/reducer.ts +++ b/next-tavla/src/Admin/scenarios/Edit/reducer.ts @@ -53,7 +53,13 @@ export function boardReducer(settings: TBoard, action: Action): TBoard { switch (action.type) { // Title operations case 'setTitle': - return { ...settings, title: action.title } + return { + ...settings, + meta: { + ...settings.meta, + title: action.title, + }, + } // Theme operations case 'changeTheme': { return { ...settings, theme: action.theme } diff --git a/next-tavla/src/Admin/scenarios/TableHeader/index.tsx b/next-tavla/src/Admin/scenarios/TableHeader/index.tsx index 0a89f4b2b..8ebc17a7a 100644 --- a/next-tavla/src/Admin/scenarios/TableHeader/index.tsx +++ b/next-tavla/src/Admin/scenarios/TableHeader/index.tsx @@ -7,6 +7,7 @@ function TableHeader() {
Navn på tavle
Link
Valg
+
Sist oppdatert
) diff --git a/next-tavla/src/Admin/scenarios/TableHeader/styles.module.css b/next-tavla/src/Admin/scenarios/TableHeader/styles.module.css index e1adcd361..8a8cd29f5 100644 --- a/next-tavla/src/Admin/scenarios/TableHeader/styles.module.css +++ b/next-tavla/src/Admin/scenarios/TableHeader/styles.module.css @@ -5,7 +5,7 @@ .tableRow { display: grid; - grid-template-columns: 3fr 5fr 1fr; + grid-template-columns: 3fr 5fr 2fr 2fr; } .tableCell { diff --git a/next-tavla/src/Admin/utils/firebase.ts b/next-tavla/src/Admin/utils/firebase.ts index e1c4dea63..5dae85b88 100644 --- a/next-tavla/src/Admin/utils/firebase.ts +++ b/next-tavla/src/Admin/utils/firebase.ts @@ -75,11 +75,33 @@ export async function setBoard(board: TBoard, uid: TUserID) { return await firestore() .collection('boards') .doc(boardId) - .set(sanitizedBoard) + .set({ + ...sanitizedBoard, + meta: { ...sanitizedBoard.meta, dateModified: Date.now() }, + }) +} + +export async function setLastActive(bid: TBoardID) { + const board = await firestore().collection('boards').doc(bid).get() + if (!board.exists) + throw new TavlaError({ + code: 'BOARD', + message: 'Board does not exist.', + }) + + firestore() + .collection('boards') + .doc(bid) + .update({ 'meta.lastActive': Date.now() }) } export async function createBoard(uid: TUserID) { - const board = await firestore().collection('boards').add({ tiles: [] }) + const board = await firestore() + .collection('boards') + .add({ + tiles: [], + meta: { created: Date.now(), dateModified: Date.now() }, + }) firestore() .collection('users') .doc(uid) diff --git a/next-tavla/src/Shared/hooks/useUpdateLastActive.ts b/next-tavla/src/Shared/hooks/useUpdateLastActive.ts new file mode 100644 index 000000000..4a1ab71b1 --- /dev/null +++ b/next-tavla/src/Shared/hooks/useUpdateLastActive.ts @@ -0,0 +1,20 @@ +import { useCallback, useEffect } from 'react' +import { TBoardID } from 'types/settings' + +function useUpdateLastActive(documentId: TBoardID | undefined) { + const updateLastActive = useCallback(async () => { + await fetch(`/api/ping/${documentId}`, { + method: 'POST', + }) + }, [documentId]) + + useEffect(() => { + updateLastActive() + const intervalId = setInterval(updateLastActive, 1000 * 60 * 60 * 24) + return () => { + clearInterval(intervalId) + } + }, [updateLastActive]) +} + +export { useUpdateLastActive } diff --git a/next-tavla/src/Shared/types/meta.ts b/next-tavla/src/Shared/types/meta.ts new file mode 100644 index 000000000..3adbf6324 --- /dev/null +++ b/next-tavla/src/Shared/types/meta.ts @@ -0,0 +1,7 @@ +export type TMeta = { + title?: string + created?: number + lastActive?: number + dateModified?: number + version?: number +} diff --git a/next-tavla/src/Shared/types/settings.ts b/next-tavla/src/Shared/types/settings.ts index ba2291d06..1fcf6fe67 100644 --- a/next-tavla/src/Shared/types/settings.ts +++ b/next-tavla/src/Shared/types/settings.ts @@ -1,12 +1,12 @@ +import { TMeta } from './meta' import { TTile } from './tile' export type TTheme = 'entur' | 'dark' | 'light' export type TBoard = { id?: TBoardID - title?: string + meta?: TMeta tiles: TTile[] - version?: number theme?: TTheme } diff --git a/next-tavla/src/Shared/utils/time.ts b/next-tavla/src/Shared/utils/time.ts index 3a40eea14..a08f99012 100644 --- a/next-tavla/src/Shared/utils/time.ts +++ b/next-tavla/src/Shared/utils/time.ts @@ -20,3 +20,15 @@ export function formatTimeStamp(timestamp: number) { minute: '2-digit', }).format(timestamp) } + +export function formatDate(date: Date) { + return date + .toLocaleDateString('no-NB', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + hour: '2-digit', + minute: '2-digit', + }) + .replace(',', '') +}