This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

refactor: replace catch-all semble route with search params

+77 -67
-42
src/webapp/app/(dashboard)/url/[...url]/layout.tsx
··· 1 - import type { Metadata } from 'next'; 2 - import Header from '@/components/navigation/header/Header'; 3 - import { Fragment } from 'react'; 4 - import { getDomain, getUrlFromSlug } from '@/lib/utils/link'; 5 - import { getUrlMetadata } from '@/features/cards/lib/dal'; 6 - 7 - interface Props { 8 - params: Promise<{ url: string[] }>; 9 - children: React.ReactNode; 10 - } 11 - 12 - export async function generateMetadata({ params }: Props): Promise<Metadata> { 13 - const { url } = await params; 14 - const formattedUrl = getUrlFromSlug(url); 15 - const { metadata } = await getUrlMetadata(formattedUrl); 16 - const domain = getDomain(formattedUrl); 17 - const title = metadata.title ? `${metadata.title} (${domain})` : formattedUrl; 18 - 19 - return { 20 - title: `Semble | ${title}`, 21 - description: `Semble page for ${title}`, 22 - openGraph: { 23 - images: [ 24 - { 25 - url: `${process.env.APP_URL}/api/opengraph/semble?url=${formattedUrl}`, 26 - width: 1200, 27 - height: 630, 28 - alt: `Semble page for ${domain}`, 29 - }, 30 - ], 31 - }, 32 - }; 33 - } 34 - 35 - export default async function Layout(props: Props) { 36 - return ( 37 - <Fragment> 38 - <Header /> 39 - {props.children} 40 - </Fragment> 41 - ); 42 - }
-23
src/webapp/app/(dashboard)/url/[...url]/page.tsx
··· 1 - import SembleContainer from '@/features/semble/containers/sembleContainer/SembleContainer'; 2 - import { getUrlFromSlug } from '@/lib/utils/link'; 3 - import SembleAside from '@/features/semble/containers/sembleAside/SembleAside'; 4 - import { Fragment, Suspense } from 'react'; 5 - import SembleAsideSkeleton from '@/features/semble/containers/sembleAside/Skeleton.SembleAside'; 6 - 7 - interface Props { 8 - params: Promise<{ url: string[] }>; 9 - } 10 - 11 - export default async function Page(props: Props) { 12 - const { url } = await props.params; 13 - const formattedUrl = getUrlFromSlug(url); 14 - 15 - return ( 16 - <Fragment> 17 - <SembleContainer url={formattedUrl} /> 18 - <Suspense fallback={<SembleAsideSkeleton />} key={formattedUrl}> 19 - <SembleAside url={formattedUrl} /> 20 - </Suspense> 21 - </Fragment> 22 - ); 23 - }
+15
src/webapp/app/(dashboard)/url/layout.tsx
··· 1 + import Header from '@/components/navigation/header/Header'; 2 + import { Fragment } from 'react'; 3 + 4 + interface Props { 5 + children: React.ReactNode; 6 + } 7 + 8 + export default async function Layout(props: Props) { 9 + return ( 10 + <Fragment> 11 + <Header /> 12 + {props.children} 13 + </Fragment> 14 + ); 15 + }
+60
src/webapp/app/(dashboard)/url/page.tsx
··· 1 + import type { Metadata } from 'next'; 2 + import { getDomain } from '@/lib/utils/link'; 3 + import { getUrlMetadata } from '@/features/cards/lib/dal'; 4 + import { redirect } from 'next/navigation'; 5 + import SembleAside from '@/features/semble/containers/sembleAside/SembleAside'; 6 + import SembleAsideSkeleton from '@/features/semble/containers/sembleAside/Skeleton.SembleAside'; 7 + import SembleContainer from '@/features/semble/containers/sembleContainer/SembleContainer'; 8 + import { Fragment, Suspense } from 'react'; 9 + 10 + interface Props { 11 + searchParams: Promise<{ id: string | undefined }>; 12 + } 13 + 14 + export async function generateMetadata({ 15 + searchParams, 16 + }: { 17 + searchParams: Promise<{ id: string | undefined }>; 18 + }): Promise<Metadata> { 19 + const { id: url } = await searchParams; 20 + 21 + if (!url) { 22 + redirect('/'); 23 + } 24 + 25 + const { metadata } = await getUrlMetadata(url); 26 + const domain = getDomain(url); 27 + const title = metadata.title ? `${metadata.title} (${domain})` : url; 28 + 29 + return { 30 + title: `Semble | ${title}`, 31 + description: `Semble page for ${title}`, 32 + openGraph: { 33 + images: [ 34 + { 35 + url: `${process.env.APP_URL}/api/opengraph/semble?url=${url}`, 36 + width: 1200, 37 + height: 630, 38 + alt: `Semble page for ${domain}`, 39 + }, 40 + ], 41 + }, 42 + }; 43 + } 44 + 45 + export default async function Page(props: Props) { 46 + const { id: url } = await props.searchParams; 47 + 48 + if (!url) { 49 + redirect('/'); 50 + } 51 + 52 + return ( 53 + <Fragment> 54 + <SembleContainer url={url} /> 55 + <Suspense fallback={<SembleAsideSkeleton />} key={url}> 56 + <SembleAside url={url} /> 57 + </Suspense> 58 + </Fragment> 59 + ); 60 + }
+1 -1
src/webapp/components/navigation/appLayout/AppLayout.tsx
··· 13 13 const { mobileOpened, desktopOpened } = useNavbarContext(); 14 14 const pathname = usePathname(); 15 15 16 - const ROUTES_WITH_ASIDE = ['/url/']; 16 + const ROUTES_WITH_ASIDE = ['/url']; 17 17 const hasAside = ROUTES_WITH_ASIDE.some((prefix) => 18 18 pathname.startsWith(prefix), 19 19 );
+1 -1
src/webapp/features/cards/components/urlCard/UrlCard.tsx
··· 36 36 37 37 const handleNavigateToSemblePage = (e: MouseEvent<HTMLElement>) => { 38 38 e.stopPropagation(); 39 - router.push(`/url/${props.cardContent.url}`); 39 + router.push(`/url?id=${props.cardContent.url}`); 40 40 }; 41 41 // TODO: add more sizes 42 42