Skip to content

Commit

Permalink
Restore LCO section on area page (#1042)
Browse files Browse the repository at this point in the history
* fix: add LCO banner back to area page
  • Loading branch information
vnugent authored Dec 26, 2023
1 parent 8b245c8 commit d683a30
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 118 deletions.
14 changes: 10 additions & 4 deletions src/app/area/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { AreaPageActions } from '../../components/AreaPageActions'
import { SubAreasSection } from './sections/SubAreasSection'
import { ClimbListSection } from './sections/ClimbListSection'
import { CLIENT_CONFIG } from '@/js/configs/clientConfig'
import { PageBanner as LCOBanner } from '@/components/lco/PageBanner'
/**
* Page cache settings
*/
Expand Down Expand Up @@ -46,7 +47,7 @@ export default async function Page ({ params }: PageWithCatchAllUuidProps): Prom
const { area } = pageData

const photoList = area?.media ?? []
const { uuid, pathTokens, ancestors, areaName, content, authorMetadata, metadata } = area
const { uuid, pathTokens, ancestors, areaName, content, authorMetadata, metadata, organizations } = area
const { description } = content
const { lat, lng } = metadata

Expand Down Expand Up @@ -105,7 +106,7 @@ export default async function Page ({ params }: PageWithCatchAllUuidProps): Prom

<div className='area-climb-page-summary-right'>
<div className='flex items-center gap-2'>
<h3>Description</h3>
<h3 className='font-bold'>Description</h3>
<span className='text-xs inline-block align-baseline'>
[
<Link
Expand All @@ -119,12 +120,17 @@ export default async function Page ({ params }: PageWithCatchAllUuidProps): Prom
</div>
{(description == null || description.trim() === '') && <EditDescriptionCTA uuid={uuid} />}
<Markdown className='wiki-content'>{description}</Markdown>
</div>

<hr className='border-1 mt-8 mb-4' />

<LCOBanner orgs={organizations} />
</div>
</div>

<hr className='border-1 my-8' />

{/* An area can only have either subareas or climbs, but not both. */}
<div className='mt-6'>
<div className='mt-8'>
<SubAreasSection area={area} />
<ClimbListSection area={area} />
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/area/[[...slug]]/sections/SubAreasSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const SubAreasSection: React.FC<{ area: AreaType } > = ({ area }) => {
<section className='w-full'>
<div className='flex items-center justify-between'>
<div className='flex items-center gap-3'>
<h3 className='flex items-center gap-4'><AreaEntityBullet />{children.length} Areas</h3>
<h3 className='flex items-center gap-4 font-bold'><AreaEntityBullet />{children.length} Areas</h3>
</div>
<Link href={`/editArea/${uuid}/general#addArea`} target='_new' className='btn btn-sm btn-accent'>
<PlusCircle size={16} /> New Areas
Expand Down
4 changes: 2 additions & 2 deletions src/app/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,14 @@ A slightly deemphasized dotted underline for a tag in order to not competing wit
}

.dialog-close-button {
@apply fixed top-0.5 left-0.5 lg:top-1 lg:left-1 z-50;
@apply absolute top-1 left-1 z-50;
}

.dialog-form-default {
@apply mt-16 lg:mt-20 px-2 lg:px-4 mb-6 !important;
}

.dialog-title {
@apply py-4 lg:py-5 left-0 top-0 w-full text-center fixed bg-base-100 bg-opacity-80 backdrop-blur-sm z-50 leading-none;
@apply py-2 w-full text-center bg-base-100 z-50 leading-none;
}
}
237 changes: 130 additions & 107 deletions src/components/lco/PageBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// import * as HoverCard from '@radix-ui/react-hover-card'
'use client'
import { HandHeart, ArrowUpRight, ArrowRight } from '@phosphor-icons/react/dist/ssr'
import { OrganizationType } from '../../js/types'
import Tooltip from '../../components/ui/Tooltip'
import { InformationCircleIcon } from '@heroicons/react/20/solid'
import { UsersIcon, ArrowUpRightIcon } from '@heroicons/react/24/outline'
import { MobileDialog, DialogContent, DialogTrigger } from '../ui/MobileDialog'

export interface LCOProfileType {
Expand Down Expand Up @@ -49,27 +47,24 @@ export const PageBanner: React.FC<PageBannerProps> = ({ orgs }) => {
const lcoList = getLcoList(orgs)

return (
<div className='grid pt-6 pb-4 lg:pb-16 lg:pt-16'>
<div className='col-span-full flex justify-start items-center pb-6'>
<h3 className='mr-4'>Local climbing organizations</h3>
<Tooltip content={
<p>Learn more about our&nbsp;
<a href='https://openbeta.substack.com/p/openbeta-and-lcos' target='_blank' rel='noreferrer' className='underline'>
initiative
</a>.
</p>
}
>
<InformationCircleIcon className='h-6 w-6' />
</Tooltip>
<div>
<div className='flex items-center flex-wrap gap-2 '>
<h3 className='font-bold'>Local climbing organizations</h3>
<span className='text-xs'>
[
<a
href='https://openbeta.substack.com/p/openbeta-and-lcos'
target='_blank' rel='noreferrer' className='hover:underline'
>
Learn more
</a>
]
</span>
</div>
<div>

<div className='mt-3 flex flex-wrap gap-6'>
{lcoList.length === 0
? (
<p className='italic text-base-content/60'>
No organizations found for this area
</p>
)
? <AddLCOCallToAction />
: (
lcoList.map((orgProfile) => (
<LcoCardTrigger key={orgProfile.id} profile={orgProfile} />
Expand All @@ -93,14 +88,18 @@ const LcoCardTrigger: React.FC<{ profile: LCOProfileType }> = ({ profile }): JSX

const IndividualBanner: React.FC<ContentProps> = ({ profile }) => (
<DialogTrigger asChild className='flex flex-row items-center gap-4'>
<div className='sm:inline-block mr-6 mb-6'>
<div className='flex items-center bg-light hover:bg-on-hover pl-5 pr-7 rounded-2xl'>
<UsersIcon className='h-10 w-10' />
<div className='py-5 pl-4 overflow-hidden'>
<p className='text-base leading-6'>{profile.name}</p>
<p className='text-xs underline'>
<a href={profile.website} target='_blank' rel='noreferrer'>{profile.website}</a>
</p>
<div className='card card-compact w-80 shadow-lg card-bordered'>
<div className='card-body overflow-hidden'>
<div className='flex items-center gap-3'>
<div className='avatar cursor-pointer'>
<HandHeart size={32} weight='duotone' className='border rounded border-base-300 p-0.5' />
</div>
<div className='overflow-hidden'>
<p className='text-base leading-6 cursor-pointer truncate'>{profile.name}</p>
<p className='text-xs underline text-secondary truncate'>
<a href={profile.website} target='_blank' rel='noreferrer' onClick={e => e.stopPropagation()}>{profile.website}</a>
</p>
</div>
</div>
</div>
</div>
Expand All @@ -114,94 +113,118 @@ interface ContentProps {
const LcoCard: React.FC<ContentProps> = ({ profile }) => {
const { name, description, email, website, facebook, instagram, report, donation } = profile
return (

<div className='grid md:grid-cols-6 px-11 pt-11 pb-16 gap-2 md:gap-4 bg-white rounded-lg'>

<div className='md:col-span-1'>
<UsersIcon className='h-12 w-12 rounded-lg border-slate-100 border' />
</div>

<div className='gap-10 md:col-span-5'>
<p className='text-base-content/60 font-semibold'>Local Climbing Organization</p>
<h2 className='card-title my-2 uppercase'>{name}</h2>
{website != null && (
<a
className='underline pb-5'
href={website}
target='_blank'
rel='noreferrer'
>
<p className='text-sm'>{website}</p>
</a>
)}
{description != null && (
<p className='whitespace-pre-line'>
{description}
</p>
)}
<div className={email == null && instagram == null && facebook == null ? ('hidden') : ('border-t border-b divide-y')}>
<div className='flex felx-row flex-wrap justify-between pt-4 md:pt-6'>
{email != null && (
<a
className='underline pb-4'
href={`mailto:${email}`}
target='_blank'
rel='noreferrer'
>
contact info
</a>
)}
{instagram != null && (
<a
className='underline pb-4'
href={instagram}
target='_blank'
rel='noreferrer'
>
instagram
</a>
)}
{facebook != null && (
<a
className='underline pb-4'
href={facebook}
target='_blank'
rel='noreferrer'
>
facebook
</a>
)}
<div className='card card-bordered'>
<div className='card-body'>
<div className='flex flex-col lg:flex-row gap-6'>
<div className='avatar'>
<HandHeart size={48} className='border rounded-btn p-1' />
</div>
</div>
<div className='space-y-4 py-6'>
<div>
{donation != null && (
<p className='text-secondary font-semibold'>Local Climbing Organization</p>
<h3 className='card-title mt-4 uppercase'>{name}</h3>
{website != null && (
<a
className='btn btn-primary btn-outline'
href={donation}
className='underline text-xs text-secondary'
href={website}
target='_blank'
rel='noreferrer'
>
Make a Donation <ArrowUpRightIcon className='ml-2 w-4 h-4' />
{website}
</a>
)}
</div>
{report != null && (
<div className='card-actions '>
<a
className='btn btn-primary btn-solid'
href={report}
target='_blank'
rel='noreferrer'
>
Report Hardware Replacement{' '}
<ArrowUpRightIcon className='ml-2 w-4 h-4' />
</a>
{description != null && (
<p className='text-base mt-2'>
{description}
</p>
)}

<SocialLinks email={email} facebook={facebook} instagram={instagram} />

<div className='card-actions flex flex-col gap-4'>
{donation != null && (
<a
className='btn btn-primary gap-2'
href={donation}
target='_blank'
rel='noreferrer'
>
Make a Donation <ArrowUpRight />
</a>
)}
{report != null && (
<a
className='btn btn-accent btn-solid gap-2'
href={report}
target='_blank'
rel='noreferrer'
>
Report Hardware Replacement{' '}
<ArrowUpRight />
</a>
)}
</div>
)}
</div>
</div>
</div>
</div>
)
}

const SocialLinks: React.FC<{ email?: string, facebook?: string, instagram?: string }> = ({ email, facebook, instagram }) => {
if (email == null && facebook == null && instagram == null) return null

return (
<div className='px-4 border-t border-b flex items-center flex-wrap gap-8 pt-4 py-6 my-6'>
{email != null && (
<a
className='underline'
href={`mailto:${email}`}
target='_blank'
rel='noreferrer'
>
contact info
</a>
)}
{instagram != null && (
<a
className='underline'
href={instagram}
target='_blank'
rel='noreferrer'
>
instagram
</a>
)}
{facebook != null && (
<a
className='underline'
href={facebook}
target='_blank'
rel='noreferrer'
>
facebook
</a>
)}
</div>
)
}

const AddLCOCallToAction: React.FC = () => {
return (
<div>
<p className='italic'>No organizations found for this area.</p>
<div className='alert mt-2'>
<p className='text-sm'>
Do you know a great local organization?&nbsp;
<a
href='https://openbeta.substack.com/p/openbeta-and-lcos'
target='_blank' rel='noreferrer'
className='link-dotted inline-flex items-center gap-1'
>
Let us know <ArrowRight />
</a>
</p>
</div>
</div>
)
}
8 changes: 4 additions & 4 deletions src/components/ui/MobileDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { ReactNode } from 'react'
import * as DialogPrimitive from '@radix-ui/react-dialog'
import { XMarkIcon } from '@heroicons/react/24/outline'
import { X as XMarkIcon } from '@phosphor-icons/react/dist/ssr'
import clx from 'classnames'
interface Props {
title?: string | ReactNode
Expand All @@ -25,13 +25,13 @@ export const DialogContent = React.forwardRef<any, Props>(
<DialogPrimitive.Title className='dialog-title'>
{title}
</DialogPrimitive.Title>
{children}
{/* Use absolute positioning to place the close button on the upper left corner */}
<DialogPrimitive.Close aria-label='Close' asChild className='dialog-close-button'>
<button className='btn btn-circle btn-ghost'>
<XMarkIcon className='w-8 h-8' />
<button className='btn btn-circle btn-ghost outline-none'>
<XMarkIcon size={24} />
</button>
</DialogPrimitive.Close>
{children}
</DialogPrimitive.Content>
</DialogPrimitive.Portal>
)
Expand Down

1 comment on commit d683a30

@vercel
Copy link

@vercel vercel bot commented on d683a30 Dec 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.