Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new full screen map #1083

Merged
merged 5 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ module.exports = {
},
async redirects () {
return [
{
source: '/map',
destination: '/maps',
permanent: true
},
{
source: '/areas/:uuid',
destination: '/area/:uuid/',
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@turf/bbox": "^6.5.0",
"@turf/line-to-polygon": "^6.5.0",
"@udecode/zustood": "^1.1.3",
"@vercel/edge": "^1.1.1",
"auth0": "^2.42.0",
"awesome-debounce-promise": "^2.1.0",
"aws-sdk": "^2.1265.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AreaPageContainer } from '@/app/components/ui/AreaPageContainer'
import { AreaPageContainer } from '@/app/(default)/components/ui/AreaPageContainer'

/**
* Loading skeleton for /area/<id> page.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import Markdown from 'react-markdown'

import PhotoMontage, { UploadPhotoCTA } from '@/components/media/PhotoMontage'
import { getArea } from '@/js/graphql/getArea'
import { StickyHeaderContainer } from '@/app/components/ui/StickyHeaderContainer'
import { StickyHeaderContainer } from '@/app/(default)/components/ui/StickyHeaderContainer'
import { AreaCrumbs } from '@/components/breadcrumbs/AreaCrumbs'
import { ArticleLastUpdate } from '@/components/edit/ArticleLastUpdate'
import { getMapHref, getFriendlySlug, getAreaPageFriendlyUrl, sanitizeName } from '@/js/utils'
import { LazyAreaMap } from '@/components/maps/AreaMap'
import { AreaPageContainer } from '@/app/components/ui/AreaPageContainer'
import { AreaPageContainer } from '@/app/(default)/components/ui/AreaPageContainer'
import { AreaPageActions } from '../../components/AreaPageActions'
import { SubAreasSection } from './sections/SubAreasSection'
import { ClimbListSection } from './sections/ClimbListSection'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ClimbList } from '@/app/editArea/[slug]/general/components/climb/ClimbListForm'
import { ClimbList } from '@/app/(default)/editArea/[slug]/general/components/climb/ClimbListForm'
import { AreaType } from '@/js/types'
/**
* Climb list section
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Link from 'next/link'
import { PlusSquare } from '@phosphor-icons/react/dist/ssr'
import { AreaList } from 'app/editArea/[slug]/general/components/AreaList'
import { AreaList } from '@/app/(default)/editArea/[slug]/general/components/AreaList'
import { AreaEntityBullet } from '@/components/cues/Entities'
import { AreaType } from '@/js/types'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Link from 'next/link'
import { PencilSimple, ArrowElbowLeftDown } from '@phosphor-icons/react/dist/ssr'
import { ShareAreaLinkButton } from '@/app/components/ShareAreaLinkButton'
import { ShareAreaLinkButton } from '@/app/(default)/components/ShareAreaLinkButton'
import { UploadPhotoButton } from '@/components/media/PhotoUploadButtons'

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use client'
import { signIn, useSession } from 'next-auth/react'

import { Logo } from 'app/header'
import { Logo } from '../header'
import { XSearchMinimal } from '@/components/search/XSearch'
import { NavMenuItem, NavMenuItemProps } from '@/components/ui/NavMenuButton'
import GitHubStars from '@/components/GitHubStars'
import ProfileNavButton from './ProfileNavButton'
import AuthenticatedProfileNavButton from '../../../components/AuthenticatedProfileNavButton'

export const DesktopHeader: React.FC = () => {
const { status } = useSession()
Expand Down Expand Up @@ -56,7 +56,7 @@ export const DesktopHeader: React.FC = () => {
let nav
switch (status) {
case 'authenticated':
nav = <ProfileNavButton isMobile={false} />
nav = <AuthenticatedProfileNavButton isMobile={false} />
break
case 'loading':
nav = (
Expand Down
21 changes: 21 additions & 0 deletions src/app/(default)/components/LandingHero.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ArrowRight } from '@phosphor-icons/react/dist/ssr'

export const LandingHero: React.FC = () => {
return (
<section className='w-full px-6 py-4'>
<h1 className='text-2xl tracking-tighter font-semibold'>Share your climbing route knowledge!</h1>
<div className='font-medium text-neutral/80'>
Join us to help improve this comprehensive climbing resource for the community.
</div>
<div className='mt-2'>
<HeroAlert />
</div>
</section>
)
}

export const HeroAlert: React.FC = () => (
<div className='mt-2 alert alert-warning'>
<span className='badge badge-sm badge-primary'>NEW</span>
<a href='/maps' className='underline flex items-center gap-1 text-sm'>Crag maps<ArrowRight size={20} /></a>
</div>)
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
'use client'
import { useSession } from 'next-auth/react'
import { Logo } from 'app/header'
import { Logo } from '../header'
import { XSearchMinimal } from '@/components/search/XSearch'
import { LoginButton, More } from '@/components/MobileAppBar'
import ProfileNavButton from './ProfileNavButton'
import AuthenticatedProfileNavButton from '../../../components/AuthenticatedProfileNavButton'

/**
* Main header for mobile
*/
export const MobileHeader: React.FC = () => {
const { status } = useSession()
const nav = status === 'authenticated' ? <ProfileNavButton /> : <LoginButton />
const nav = status === 'authenticated' ? <AuthenticatedProfileNavButton /> : <LoginButton />
return (
<header className='flex lg:hidden items-center justify-between gap-6'>
<Logo />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Logo, LogoSize } from 'app/header'
import { Logo, LogoSize } from '../header'
/**
* Page footer
*/
export const PageFooter: React.FC = () => {
return (
<footer className='footer p-10 bg-base-200 bg-base-content text-base-100 snap-start snap-normal'>
<footer className='relative footer p-10 bg-base-200 bg-base-content text-base-100 snap-start snap-normal'>
<aside>
<div className='border-2 border-accent py-3 pl-2 pr-4 rounded-full'><Logo size={LogoSize.md} className='fill-accent' /></div>
<p><span className='font-semibold text-lg'>OpenBeta</span><br /><span className='tracking-tight font-sm'>Free climbing database built & run by climbers.</span></p>
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { GallerySkeleton } from '@/components/media/PhotoMontage'
import React from 'react'
import { AreaPageActionsSkeleton } from '../AreaPageActions'
import { HeroAlert } from '../LandingHero'

/**
* Area page containter. Show loading skeleton if no params are provided.
Expand All @@ -14,7 +15,10 @@ export const AreaPageContainer: React.FC<{
}> = ({ photoGallery, pageActions, breadcrumbs, map, children }) => {
return (
<article>
<div className='p-4 mx-auto max-w-5xl xl:max-w-7xl'>
<div className='px-4 mb-2'>
<HeroAlert />
</div>
<div className='px-4 mx-auto max-w-5xl xl:max-w-7xl'>
{photoGallery == null ? <GallerySkeleton /> : photoGallery}
<div className='flex justify-end py-4 border-b'>
{pageActions == null ? <AreaPageActionsSkeleton /> : pageActions}
Expand Down
7 changes: 5 additions & 2 deletions src/app/edit/page.tsx → src/app/(default)/edit/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { getChangeHistoryServerSide } from '../../js/graphql/contribAPI'
import RecentChangeHistory from '@/components/edit/RecentChangeHistory'
import { ReactElement } from 'react'
import { Metadata } from 'next'

import { getChangeHistoryServerSide } from '@/js/graphql/contribAPI'
import RecentChangeHistory from '@/components/edit/RecentChangeHistory'

export const metadata: Metadata = {
title: 'Contribute to OpenBeta',
description: 'Share your climbing adventure photos and contribute to the climbing route catalog.'
}

export const revalidate = 3600

export default async function Page (): Promise<ReactElement> {
const history = await getChangeHistoryServerSide()
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useSession } from 'next-auth/react'
import { useRouter } from 'next/navigation'
import { WarningOctagon } from '@phosphor-icons/react/dist/ssr'

import { SingleEntryForm } from 'app/editArea/[slug]/components/SingleEntryForm'
import { SingleEntryForm } from '@/app/(default)/editArea/[slug]/components/SingleEntryForm'
import { DashboardInput } from '@/components/ui/form/Input'
import useUpdateAreasCmd from '@/js/hooks/useUpdateAreasCmd'
import { AreaType } from '@/js/types'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'
import { useSession } from 'next-auth/react'

import { SingleEntryForm } from 'app/editArea/[slug]/components/SingleEntryForm'
import { SingleEntryForm } from '@/app/(default)/editArea/[slug]/components/SingleEntryForm'
import { AREA_DESCRIPTION_FORM_VALIDATION_RULES } from '@/components/edit/EditAreaForm'
import useUpdateAreasCmd from '@/js/hooks/useUpdateAreasCmd'
import { MarkdownTextArea } from '@/components/ui/form/MarkdownTextArea'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'
import { useSession } from 'next-auth/react'

import { SingleEntryForm } from 'app/editArea/[slug]/components/SingleEntryForm'
import { SingleEntryForm } from '@/app/(default)/editArea/[slug]/components/SingleEntryForm'
import { AREA_LATLNG_FORM_VALIDATION_RULES } from '@/components/edit/EditAreaForm'
import { DashboardInput } from '@/components/ui/form/Input'
import useUpdateAreasCmd from '@/js/hooks/useUpdateAreasCmd'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { useSession } from 'next-auth/react'
import { ValidationValueMessage } from 'react-hook-form'

import { SingleEntryForm } from 'app/editArea/[slug]/components/SingleEntryForm'
import { SingleEntryForm } from '@/app/(default)/editArea/[slug]/components/SingleEntryForm'
import { DashboardInput } from '@/components/ui/form/Input'
import useUpdateAreasCmd from '@/js/hooks/useUpdateAreasCmd'
import { AREA_NAME_FORM_VALIDATION_RULES } from '@/components/edit/EditAreaForm'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { useSession } from 'next-auth/react'
import { useRouter } from 'next/navigation'

import { SingleEntryForm } from 'app/editArea/[slug]/components/SingleEntryForm'
import { SingleEntryForm } from '@/app/(default)/editArea/[slug]/components/SingleEntryForm'
import useUpdateAreasCmd from '@/js/hooks/useUpdateAreasCmd'
import { AreaType } from '@/js/types'
import { AreaDesignationRadioGroup, areaDesignationToDb, areaDesignationToForm, AreaTypeFormProp } from '@/components/edit/form/AreaDesignationRadioGroup'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default async function EditAreaDashboardLayout ({
}): Promise<any> {
const { area: { uuid, pathTokens, ancestors, areaName, metadata: { leaf } } } = await getPageDataForEdit(params.slug)
return (
<div>
<div className='relative w-full h-full'>
<div className='px-12 pt-8 pb-4'>
<div className='text-3xl tracking-tight font-semibold'>Edit area</div>

Expand All @@ -35,7 +35,7 @@ export default async function EditAreaDashboardLayout ({
</div>
<div className='flex bg-base-200 flex-col lg:flex-row py-12'>
<SidebarNav slug={params.slug} canAddAreas={!leaf} canAddClimbs={leaf} />
<main className='w-full px-2 lg:px-16'>
<main className='relative h-full w-full px-2 lg:px-16'>
{children}
</main>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { SortableContext, rectSortingStrategy, sortableKeyboardCoordinates, arra
import clx from 'classnames'
import { DotsSixVertical } from '@phosphor-icons/react/dist/ssr'

import { SingleEntryForm } from 'app/editArea/[slug]/components/SingleEntryForm'
import { SingleEntryForm } from '@/app/(default)/editArea/[slug]/components/SingleEntryForm'
import { AreaType } from '@/js/types'
import { areaLeftRightIndexComparator } from '@/js/utils'
import { SortableClimbItem } from '../../../manageClimbs/components/sorting/SortableClimbItem'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { useSession } from 'next-auth/react'
import { useRouter } from 'next/navigation'

import { SingleEntryForm } from 'app/editArea/[slug]/components/SingleEntryForm'
import { SingleEntryForm } from '@/app/(default)/editArea/[slug]/components/SingleEntryForm'
import useUpdateClimbsCmd from '@/js/hooks/useUpdateClimbsCmd'
import { DynamicClimbInputList } from './DynamicClimbInputList'
import { GradeContexts } from '@/js/grades/Grade'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { SortableContext, rectSortingStrategy, sortableKeyboardCoordinates, arra
import clx from 'classnames'
import { DotsSixVertical } from '@phosphor-icons/react/dist/ssr'

import { SingleEntryForm } from 'app/editArea/[slug]/components/SingleEntryForm'
import { SingleEntryForm } from '@/app/(default)/editArea/[slug]/components/SingleEntryForm'
import { ClimbType } from '@/js/types'
import { climbLeftRightIndexComparator } from '@/js/utils'
import { SortableClimbItem } from './SortableClimbItem'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Metadata } from 'next'
import { DashboardPageProps, getPageDataForEdit } from '../general/page'
import { PageContainer, SectionContainer } from '../components/EditAreaContainers'
import { AddClimbsForm } from './components/AddClimbsForm'
import { ClimbListSection } from '@/app/area/[[...slug]]/sections/ClimbListSection'
import { ClimbListSection } from '@/app/(default)/area/[[...slug]]/sections/ClimbListSection'
import { SortClimbsForm } from './components/sorting/SortClimbsForm'

// Opt out of caching for all data requests in the route segment
Expand Down
File renamed without changes.
10 changes: 5 additions & 5 deletions src/app/layout.tsx → src/app/(default)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Metadata } from 'next'
import '../../public/fonts/fonts.css'
import './global.css'
import '@/public/fonts/fonts.css'
import '../global.css'
import Header from './header'
import { PageFooter } from './components/PageFooter'
import { NextAuthProvider } from './components/NextAuthProvider'
import { NextAuthProvider } from '@/components/auth/NextAuthProvider'
import { ReactToastifyProvider } from './components/ReactToastifyProvider'
import { BlockingAlertUploadingInProgress } from './components/ui/GlobalAlerts'

Expand All @@ -26,8 +26,8 @@ export default function RootLayout ({
children: React.ReactNode
}): any {
return (
<html lang='en' className='snap-proximity snap-y'>
<body>
<html lang='en' className='snap-proximity snap-y scroll-smooth'>
<body className='relative'>
<NextAuthProvider>
<Header />
<div>
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/app/page.tsx → src/app/(default)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { RecentContributionsMap } from './components/recent/RecentContributionsM
/**
* Cache duration in seconds
*/
export const revalidate = 3600
export const dynamic = 'force-dynamic'

/**
* Root home page
Expand Down
17 changes: 17 additions & 0 deletions src/app/(maps)/components/ProfileMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client'
import { SessionProvider } from 'next-auth/react'
import { House } from '@phosphor-icons/react/dist/ssr'
import AuthenticatedProfileNavButton from '@/components/AuthenticatedProfileNavButton'

export const ProfileMenu: React.FC = () => {
return (
<SessionProvider>
<div className='absolute right-4 top-4 z-50'>
<nav className='flex items-center gap-2'>
<a className='btn glass' href='/'><House size={18} />Home</a>
<AuthenticatedProfileNavButton isMobile={false} />
</nav>
</div>
</SessionProvider>
)
}
31 changes: 31 additions & 0 deletions src/app/(maps)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'mapbox-gl/dist/mapbox-gl.css'
import { Metadata } from 'next'
import '@/public/fonts/fonts.css'
import './../global.css'

/**
* Root layout for `/maps` route
*/
export default function MapsRootLayout ({
children
}: {
children: React.ReactNode
}): any {
return (
<html lang='en'>
<body className='relative'>
{children}
</body>
</html>
)
}

export const metadata: Metadata = {
title: 'Open climb maps',
description: 'Free rock climbing platform',
openGraph: {
description: 'OpenBeta is a free climbing platform. Join the community and share your knowledge today.',
images: '/south-africa-og.jpeg'
},
metadataBase: new URL(`https://${process.env.VERCEL_URL ?? 'http://localhost:3000'}`)
}
15 changes: 15 additions & 0 deletions src/app/(maps)/maps/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { GlobalMap } from '@/components/maps/GlobalMap'
import { ProfileMenu } from '../components/ProfileMenu'

export const dynamic = 'force-dynamic'

export default async function MapPage (): Promise<any> {
return (
<div className='w-full h-full'>
<ProfileMenu />
<GlobalMap
showFullscreenControl={false}
/>
</div>
)
}
18 changes: 18 additions & 0 deletions src/app/api/geo/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { NextRequest, NextResponse } from 'next/server'
import { geolocation } from '@vercel/edge'

export const runtime = 'edge'

/**
* Return latitude and longitude of the visitor. Only works when deploying on Vercel.
* Endpoint: `/api/geo`
*/
export async function GET (request: NextRequest): Promise<any> {
const geo = geolocation(request)
const longitude = geo?.longitude
const latitude = geo?.latitude
if (longitude != null && latitude != null) {
return NextResponse.json({ longitude: parseFloat(longitude), latitude: parseFloat(latitude) }, { status: 200 })
}
return NextResponse.json({ message: 'No geo data available.' }, { status: 503 })
}
Loading
Loading