From 57ed2c5e9463a72915204afc6084405787e2fe28 Mon Sep 17 00:00:00 2001 From: Sonny Date: Thu, 16 May 2024 18:53:53 +0200 Subject: [PATCH] feat: migrate from paths constant to new route management system --- Dockerfile | 1 + app/constants/paths.ts | 27 ------------------- app/controllers/users_controller.ts | 14 +++++----- app/exceptions/handler.ts | 3 +-- app/middleware/auth_middleware.ts | 4 +-- .../common/navigation/back_to_dashboard.tsx | 4 +-- .../collection/collection_container.tsx | 2 +- .../collection/header/collection_controls.tsx | 11 +++++--- .../dashboard/link/link_controls.tsx | 19 +++++++++---- inertia/components/dashboard/link/no_item.tsx | 13 ++++++--- inertia/components/footer/footer.tsx | 5 ++-- inertia/components/layouts/form_layout.tsx | 6 ++--- inertia/components/navbar/navbar.tsx | 9 ++++--- inertia/lib/search.tsx | 5 ++-- inertia/pages/dashboard.tsx | 7 ++--- inertia/pages/login.tsx | 15 +++++------ src/extensions.ts | 2 ++ start/routes/app.ts | 3 +++ start/routes/collection.ts | 2 ++ start/routes/link.ts | 5 ++++ 20 files changed, 82 insertions(+), 75 deletions(-) diff --git a/Dockerfile b/Dockerfile index bcc49cf..f3af508 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,6 +22,7 @@ FROM base as build WORKDIR /app COPY --from=deps /app/node_modules /app/node_modules ADD . . +RUN node ace izzy:routes RUN node ace build # Production stage diff --git a/app/constants/paths.ts b/app/constants/paths.ts index 31e6598..811fb3b 100644 --- a/app/constants/paths.ts +++ b/app/constants/paths.ts @@ -1,31 +1,4 @@ const PATHS = { - AUTH: { - LOGIN: '/login', - LOGOUT: '/auth/logout', - GOOGLE: '/auth/google', - }, - HOME: '/', - DASHBOARD: '/dashboard', - SHARED: '/shared', - PRIVACY: '/privacy', - TERMS: '/terms', - ADMIN: '/admin', - COLLECTION: { - CREATE: '/collections/create', - EDIT: '/collections/edit', - REMOVE: '/collections/remove', - }, - LINK: { - CREATE: '/link/create', - EDIT: '/link/edit', - REMOVE: '/link/remove', - }, - API: { - COLLECTION: '/collections', - LINK: '/api/link', - }, - NOT_FOUND: '/404', - SERVER_ERROR: '/505', AUTHOR: 'https://www.sonny.dev/', REPO_GITHUB: 'https://github.com/Sonny93/my-links', EXTENSION: diff --git a/app/controllers/users_controller.ts b/app/controllers/users_controller.ts index 1d3963d..b2ed31d 100644 --- a/app/controllers/users_controller.ts +++ b/app/controllers/users_controller.ts @@ -1,10 +1,10 @@ -import PATHS from '#constants/paths'; import User from '#models/user'; import type { HttpContext } from '@adonisjs/core/http'; import logger from '@adonisjs/core/services/logger'; +import { RouteName } from '@izzyjs/route/types'; export default class UsersController { - private redirectTo = PATHS.HOME; + private redirectTo: RouteName = 'auth.login'; login({ inertia }: HttpContext) { return inertia.render('login'); @@ -17,17 +17,17 @@ export default class UsersController { if (google.accessDenied()) { // TODO: translate error messages + show them in UI session.flash('flash', 'Access was denied'); - return response.redirect(this.redirectTo); + return response.redirectToNamedRoute(this.redirectTo); } if (google.stateMisMatch()) { session.flash('flash', 'Request expired. Retry again'); - return response.redirect(this.redirectTo); + return response.redirectToNamedRoute(this.redirectTo); } if (google.hasError()) { session.flash('flash', google.getError() || 'Something went wrong'); - return response.redirect(this.redirectTo); + return response.redirectToNamedRoute(this.redirectTo); } const { @@ -56,13 +56,13 @@ export default class UsersController { session.flash('flash', 'Successfully authenticated'); logger.info(`[${user.email}] auth success`); - response.redirect(PATHS.DASHBOARD); + response.redirectToNamedRoute('dashboard'); } async logout({ auth, response, session }: HttpContext) { await auth.use('web').logout(); session.flash('flash', 'Successfully disconnected'); logger.info(`[${auth.user?.email}] disconnected successfully`); - response.redirect(this.redirectTo); + response.redirectToNamedRoute(this.redirectTo); } } diff --git a/app/exceptions/handler.ts b/app/exceptions/handler.ts index bd0082c..27fc76b 100644 --- a/app/exceptions/handler.ts +++ b/app/exceptions/handler.ts @@ -1,4 +1,3 @@ -import PATHS from '#constants/paths'; import { ExceptionHandler, HttpContext } from '@adonisjs/core/http'; import app from '@adonisjs/core/services/app'; import type { @@ -38,7 +37,7 @@ export default class HttpExceptionHandler extends ExceptionHandler { */ async handle(error: unknown, ctx: HttpContext) { if (error instanceof errors.E_ROW_NOT_FOUND) { - return ctx.response.redirect(PATHS.DASHBOARD); + return ctx.response.redirectToNamedRoute('dashboard'); } return super.handle(error, ctx); } diff --git a/app/middleware/auth_middleware.ts b/app/middleware/auth_middleware.ts index 359d88e..37d881e 100644 --- a/app/middleware/auth_middleware.ts +++ b/app/middleware/auth_middleware.ts @@ -1,7 +1,7 @@ -import PATHS from '#constants/paths'; import type { Authenticators } from '@adonisjs/auth/types'; import type { HttpContext } from '@adonisjs/core/http'; import type { NextFn } from '@adonisjs/core/types/http'; +import { route } from '@izzyjs/route/client'; /** * Auth middleware is used authenticate HTTP requests and deny @@ -11,7 +11,7 @@ export default class AuthMiddleware { /** * The URL to redirect to, when authentication fails */ - redirectTo = PATHS.AUTH.LOGIN; + redirectTo = route('auth.login').url; async handle( ctx: HttpContext, diff --git a/inertia/components/common/navigation/back_to_dashboard.tsx b/inertia/components/common/navigation/back_to_dashboard.tsx index 32b9ce7..b48a42a 100644 --- a/inertia/components/common/navigation/back_to_dashboard.tsx +++ b/inertia/components/common/navigation/back_to_dashboard.tsx @@ -1,6 +1,6 @@ import KEYS from '#constants/keys'; -import PATHS from '#constants/paths'; import { router } from '@inertiajs/react'; +import { route } from '@izzyjs/route/client'; import { ReactNode } from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; import useGlobalHotkeys from '~/hooks/use_global_hotkeys'; @@ -13,7 +13,7 @@ export default function BackToDashboard({ children }: { children: ReactNode }) { useHotkeys( KEYS.ESCAPE_KEY, () => { - router.visit(appendCollectionId(PATHS.DASHBOARD, collectionId)); + router.visit(appendCollectionId(route('dashboard').url, collectionId)); }, { enabled: globalHotkeysEnabled, enableOnFormTags: ['INPUT'] } ); diff --git a/inertia/components/dashboard/collection/collection_container.tsx b/inertia/components/dashboard/collection/collection_container.tsx index 020eb07..4f091c5 100644 --- a/inertia/components/dashboard/collection/collection_container.tsx +++ b/inertia/components/dashboard/collection/collection_container.tsx @@ -21,7 +21,7 @@ const LinksWrapper = styled.div({ const CollectionHeaderWrapper = styled.h2(({ theme }) => ({ fontWeight: 400, color: theme.colors.font, - paddingInline: '0.8em 1.1em', + paddingRight: '1.1em', display: 'flex', gap: '0.4em', alignItems: 'center', diff --git a/inertia/components/dashboard/collection/header/collection_controls.tsx b/inertia/components/dashboard/collection/header/collection_controls.tsx index e78dbb5..7aec8ab 100644 --- a/inertia/components/dashboard/collection/header/collection_controls.tsx +++ b/inertia/components/dashboard/collection/header/collection_controls.tsx @@ -1,5 +1,5 @@ -import PATHS from '#constants/paths'; import type Collection from '#models/collection'; +import { route } from '@izzyjs/route/client'; import { BsThreeDotsVertical } from 'react-icons/bs'; import { GoPencil } from 'react-icons/go'; import { IoIosAddCircleOutline } from 'react-icons/io'; @@ -14,16 +14,19 @@ const CollectionControls = ({ collectionId: Collection['id']; }) => ( } svgSize={18}> - + Add Edit Delete diff --git a/inertia/components/dashboard/link/link_controls.tsx b/inertia/components/dashboard/link/link_controls.tsx index bf4db2c..85ceca6 100644 --- a/inertia/components/dashboard/link/link_controls.tsx +++ b/inertia/components/dashboard/link/link_controls.tsx @@ -1,7 +1,7 @@ -import PATHS from '#constants/paths'; import type Link from '#models/link'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; +import { route } from '@izzyjs/route/client'; import { useCallback } from 'react'; import { AiFillStar, AiOutlineStar } from 'react-icons/ai'; import { BsThreeDotsVertical } from 'react-icons/bs'; @@ -48,9 +48,12 @@ export default function LinkControls({ link }: { link: Link }) { ); const onFavorite = () => { + const editRoute = route('link.edit', { + params: { id: link.id }, + }); makeRequest({ - url: `${PATHS.API.LINK}/${link.id}`, - method: 'PUT', + url: editRoute.url, + method: editRoute.method, body: { name: link.name, url: link.url, @@ -80,12 +83,18 @@ export default function LinkControls({ link }: { link: Link }) { )} Edit Delete diff --git a/inertia/components/dashboard/link/no_item.tsx b/inertia/components/dashboard/link/no_item.tsx index f34ab2c..df7410c 100644 --- a/inertia/components/dashboard/link/no_item.tsx +++ b/inertia/components/dashboard/link/no_item.tsx @@ -1,6 +1,6 @@ -import PATHS from '#constants/paths'; import styled from '@emotion/styled'; import { Link } from '@inertiajs/react'; +import { route } from '@izzyjs/route/client'; import { useTranslation } from 'react-i18next'; import useActiveCollection from '~/hooks/use_active_collection'; import { appendCollectionId } from '~/lib/navigation'; @@ -30,7 +30,9 @@ export function NoCollection() { return ( {t('select-collection')} - {t('or-create-one')} + + {t('or-create-one')} + ); } @@ -51,7 +53,12 @@ export function NoLink() { ), }} /> - + {t('link.create')} diff --git a/inertia/components/footer/footer.tsx b/inertia/components/footer/footer.tsx index 9366087..3a07e71 100644 --- a/inertia/components/footer/footer.tsx +++ b/inertia/components/footer/footer.tsx @@ -4,6 +4,7 @@ import { Link } from '@inertiajs/react'; import { useTranslation } from 'react-i18next'; import ExternalLink from '~/components/common/external_link'; import packageJson from '../../../package.json'; +import { route } from '@izzyjs/route/client'; const FooterStyle = styled.footer(({ theme }) => ({ fontSize: '0.9em', @@ -21,9 +22,9 @@ export default function Footer() { return (
- {t('privacy')} + {t('privacy')} {' • '} - {t('terms')} + {t('terms')} {' • '} Extension
diff --git a/inertia/components/layouts/form_layout.tsx b/inertia/components/layouts/form_layout.tsx index 0a6b65d..ed4b627 100644 --- a/inertia/components/layouts/form_layout.tsx +++ b/inertia/components/layouts/form_layout.tsx @@ -1,11 +1,11 @@ import styled from '@emotion/styled'; import { Link } from '@inertiajs/react'; +import { route } from '@izzyjs/route/client'; import { FormEvent, ReactNode } from 'react'; import Button from '~/components/common/form/_button'; import Form from '~/components/common/form/_form'; -import BaseLayout from './_base_layout'; import { appendCollectionId } from '~/lib/navigation'; -import PATHS from '#constants/paths'; +import BaseLayout from './_base_layout'; const FormLayoutStyle = styled.div(({ theme }) => ({ height: 'fit-content', @@ -49,7 +49,7 @@ const FormLayout = ({ {!disableHomeLink && ( - + ← Back to home )} diff --git a/inertia/components/navbar/navbar.tsx b/inertia/components/navbar/navbar.tsx index 2c0104b..579a506 100644 --- a/inertia/components/navbar/navbar.tsx +++ b/inertia/components/navbar/navbar.tsx @@ -1,5 +1,6 @@ import styled from '@emotion/styled'; import { Link } from '@inertiajs/react'; +import { route } from '@izzyjs/route/client'; import { IoIosLogOut } from 'react-icons/io'; import Dropdown from '~/components/common/dropdown/dropdown'; import { DropdownItemLink } from '~/components/common/dropdown/dropdown_item'; @@ -50,7 +51,7 @@ export default function Navbar() {