From cd06997caf17905be22bbb547cb8878fa8adbdb7 Mon Sep 17 00:00:00 2001 From: viet nguyen Date: Sun, 26 Nov 2023 10:11:02 -0800 Subject: [PATCH] add main action bar to area page --- src/app/area/[...slug]/page.tsx | 40 ++++++---------------- src/app/components/ShareAreaLinkButton.tsx | 37 ++++++++++++++++++++ src/components/area/areaMap.tsx | 2 +- src/components/ui/Tooltip.tsx | 34 +++++++++++++----- src/js/utils.ts | 8 +++++ 5 files changed, 82 insertions(+), 39 deletions(-) create mode 100644 src/app/components/ShareAreaLinkButton.tsx diff --git a/src/app/area/[...slug]/page.tsx b/src/app/area/[...slug]/page.tsx index 0afc88472..d520fa081 100644 --- a/src/app/area/[...slug]/page.tsx +++ b/src/app/area/[...slug]/page.tsx @@ -1,8 +1,6 @@ -import Link from 'next/link' import { notFound, redirect } from 'next/navigation' -import slugify from 'slugify' import { validate } from 'uuid' -import { MapPinLine, PlusCircle } from '@phosphor-icons/react/dist/ssr' +import { MapPinLine } from '@phosphor-icons/react/dist/ssr' import 'mapbox-gl/dist/mapbox-gl.css' import Markdown from 'react-markdown' @@ -11,11 +9,11 @@ import { getArea } from '@/js/graphql/getArea' import { StickyHeaderContainer } from '@/app/components/ui/StickyHeaderContainer' import { GluttenFreeCrumbs } from '@/components/ui/BreadCrumbs' import { ArticleLastUpdate } from '@/components/edit/ArticleLastUpdate' -import { getMapHref } from '@/js/utils' +import { getMapHref, getFriendlySlug } from '@/js/utils' import AreaMap from '@/components/area/areaMap' import { PageContainer } from '@/app/components/ui/PageContainer' -import { AreaList } from 'app/editArea/[slug]/general/components/AreaList' -import { AreaEntityBullet } from '@/components/cues/Entities' +import { AreaPageActions } from '../../components/AreaPageActions' +import { SubAreasSection } from './SubAreasSection' /** * Cache duration in seconds @@ -35,7 +33,7 @@ export default async function Page ({ params }: PageWithCatchAllUuidProps): Prom notFound() } - const optionalNamedSlug = slugify(params.slug?.[1] ?? '', { lower: true, strict: true }).substring(0, 50) + const userProvidedSlug = getFriendlySlug(params.slug?.[1] ?? '') const { area } = pageData @@ -44,10 +42,10 @@ export default async function Page ({ params }: PageWithCatchAllUuidProps): Prom const { description } = content const { lat, lng } = metadata - const friendlySlug = slugify(areaName, { lower: true, strict: true }).substring(0, 50) + const correctSlug = getFriendlySlug(areaName) - if (friendlySlug !== optionalNamedSlug) { - redirect(`/area/${uuid}/${friendlySlug}`) + if (correctSlug !== userProvidedSlug) { + redirect(`/area/${uuid}/${correctSlug}`) } return ( @@ -91,7 +89,9 @@ export default async function Page ({ params }: PageWithCatchAllUuidProps): Prom + +

Description

{description} @@ -99,25 +99,7 @@ export default async function Page ({ params }: PageWithCatchAllUuidProps): Prom
-
-
-
-

{area.children.length} Areas

- {/* - - */} -
- - - -
- -
- - -
+ ) } diff --git a/src/app/components/ShareAreaLinkButton.tsx b/src/app/components/ShareAreaLinkButton.tsx new file mode 100644 index 000000000..7c5766526 --- /dev/null +++ b/src/app/components/ShareAreaLinkButton.tsx @@ -0,0 +1,37 @@ +'use client' +import { useState, useEffect } from 'react' +import { LinkSimple, Check } from '@phosphor-icons/react/dist/ssr' + +import { getFriendlySlug } from '@/js/utils' +import { ControlledTooltip } from '@/components/ui/Tooltip' + +/** + * Copy area link to clipboard button + */ +export const ShareAreaLinkButton: React.FC<{ uuid: string, areaName: string }> = ({ uuid, areaName }) => { + const slug = getFriendlySlug(areaName) + const url = `https://openbeta.io/area/${uuid}/${slug}` + + const [clicked, setClicked] = useState(false) + + useEffect(() => { + let timerId: NodeJS.Timeout + if (clicked) { + timerId = setTimeout(() => setClicked(false), 3000) + } + return () => clearTimeout(timerId) + }, [clicked]) + + return ( + Copied } open={clicked}> + + + ) +} diff --git a/src/components/area/areaMap.tsx b/src/components/area/areaMap.tsx index 801fcb6af..c17adea65 100644 --- a/src/components/area/areaMap.tsx +++ b/src/components/area/areaMap.tsx @@ -67,7 +67,7 @@ export default function AreaMap (props: AreaMapProps): JSX.Element {
{children} {enabled && - + {content} - - } + } ) } + +export const ControlledTooltip: React.FC<{ open: boolean, content: React.ReactNode, children: React.ReactNode }> = ({ open, content, children }) => ( + + {children} + + {content} + + ) + +/** + * Tooltip body + */ +const Content: React.FC<{ children: React.ReactNode }> = ({ children }) => ( + + {children} + + +) diff --git a/src/js/utils.ts b/src/js/utils.ts index 48742a3ae..dcb43aa9c 100644 --- a/src/js/utils.ts +++ b/src/js/utils.ts @@ -1,3 +1,5 @@ +import slugify from 'slugify' + import { ClimbTypeToColor } from './constants' import { formatDistanceToNowStrict, differenceInYears, format } from 'date-fns' @@ -261,3 +263,9 @@ export const relayMediaConnectionToMediaArray = (mediaConnection: MediaConnectio if (mediaConnection == null) return [] return mediaConnection.edges.map(entry => entry.node) } + +/** + * Convert climb/area name to url-friendly slug + * @param name + */ +export const getFriendlySlug = (name: string): string => slugify(name, { lower: true, strict: true }).substring(0, 50)