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

fix: disable coordinates edit for non-leaf areas #1102

Merged
merged 3 commits into from
Feb 22, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use client'
import { EntityIcon, EType } from '../general/components/AreaItem'
import { SidebarNavProps } from './SidebarNav'

/**
* Show area attributes in a small panel
*/
export const AreaAttributesPanel: React.FC<Omit<SidebarNavProps, 'slug'>> = ({ canAddAreas, canAddClimbs, areaCount, climbCount, isLeaf, isBoulder }) => {
let type: EType
if (isLeaf) {
type = isBoulder ? 'boulder' : 'crag'
} else {
type = 'area'
}
return (
<section>
<p className='pl-4 pb-1 font-semibold text-secondary text-sm uppercase'>Area attributes</p>

<div className='bg-base-100 rounded-box border p-4'>
<div className='flex flex-col gap-3 text-base-300 text-xs w-full '>

<div className='flex items-center gap-2 justify-between'>
<span className='text-scondary'>Entity type</span> <span className='text-primary font-semibold'><EntityIcon type={type} size={16} /></span>
</div>

<hr />

<div className='flex items-center gap-2 justify-between'>
<span className='text-scondary'>Crag</span> <span className='text-primary font-semibold'>{booleanToYesNo(isLeaf)}</span>
</div>
<div className='flex items-center gap-2 justify-between'>
<span className='text-scondary'>Boulder</span> <span className='text-primary font-semibold'>{booleanToYesNo(isBoulder)}</span>
</div>

<hr />

<div className='flex items-center gap-2 justify-between'>
<span className='text-scondary'>Child areas</span> <span className='text-primary font-semibold'>{areaCount}</span>
</div>
<div className='flex items-center gap-2 justify-between'>
<span className='text-scondary'>Climbs</span> <span className='text-primary font-semibold'>{climbCount}</span>
</div>

<hr />

<div className='flex items-center gap-2 justify-between'>
<span className='text-scondary'>Can add child areas?</span> <span className='text-primary font-semibold'>{booleanToYesNo(canAddAreas)}</span>
</div>
<div className='flex items-center gap-2 justify-between'>
<span className='text-scondary'>Can add climbs?</span> <span className='text-primary font-semibold'>{booleanToYesNo(canAddClimbs)}</span>
</div>
</div>
</div>
</section>
)
}

const booleanToYesNo = (bool: boolean): string => bool ? 'YES' : 'NO'
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@
import clx from 'classnames'
import { usePathname } from 'next/navigation'
import { Article, Plus } from '@phosphor-icons/react/dist/ssr'
import { EntityIcon } from './general/components/AreaItem'
import { EntityIcon } from '../general/components/AreaItem'
import { AreaAttributesPanel } from './AreaAttributesPanel'

export interface SidebarNavProps {
slug: string
canAddAreas: boolean
canAddClimbs: boolean
areaCount: number
climbCount: number
isLeaf: boolean
isBoulder: boolean
}
/**
* Sidebar navigation for area edit
*/
export const SidebarNav: React.FC<{ slug: string, canAddAreas: boolean, canAddClimbs: boolean }> = ({ slug, canAddAreas, canAddClimbs }) => {
export const SidebarNav: React.FC<SidebarNavProps> = ({ slug, canAddAreas, canAddClimbs, areaCount, climbCount, isLeaf, isBoulder }) => {
const activePath = usePathname()
/**
* Disable menu item's hover/click when own page is showing
Expand Down Expand Up @@ -54,7 +64,7 @@ export const SidebarNav: React.FC<{ slug: string, canAddAreas: boolean, canAddCl
</li>
</ul>

<div className='w-56 mt-4'>
<div className='w-56 my-4'>
<hr className='border-t my-2' />
<a
href={`/editArea/${slug}/general#addArea`}
Expand All @@ -67,7 +77,7 @@ export const SidebarNav: React.FC<{ slug: string, canAddAreas: boolean, canAddCl

<a
href={`/editArea/${slug}/manageClimbs`}
className={clx(canAddClimbs ? '' : 'cursor-not-allowed pointer-events-none', 'block py-1')}
className={clx(canAddClimbs ? '' : 'cursor-not-allowed pointer-events-none', 'block py-2')}
>
<button disabled={!canAddClimbs} className='btn btn-accent btn-outline btn-block justify-start'>
<Plus size={20} weight='bold' /> Add climbs
Expand All @@ -77,6 +87,17 @@ export const SidebarNav: React.FC<{ slug: string, canAddAreas: boolean, canAddCl
<hr className='border-t my-2' />

</div>

<div className='my-6'>
<AreaAttributesPanel
canAddAreas={canAddAreas}
canAddClimbs={canAddClimbs}
areaCount={areaCount}
climbCount={climbCount}
isLeaf={isLeaf}
isBoulder={isBoulder}
/>
</div>
</div>
</nav>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { DashboardInput } from '@/components/ui/form/Input'
import useUpdateAreasCmd from '@/js/hooks/useUpdateAreasCmd'
import { parseLatLng } from '@/components/crag/cragSummary'

export const AreaLatLngForm: React.FC<{ initLat: number, initLng: number, uuid: string }> = ({ uuid, initLat, initLng }) => {
export const AreaLatLngForm: React.FC<{ initLat: number, initLng: number, uuid: string, isLeaf: boolean }> = ({ uuid, initLat, initLng, isLeaf }) => {
const session = useSession({ required: true })
const { updateOneAreaCmd } = useUpdateAreasCmd({
areaId: uuid,
Expand All @@ -29,12 +29,15 @@ export const AreaLatLngForm: React.FC<{ initLat: number, initLng: number, uuid:
}
}}
>
<DashboardInput
name='latlngStr'
label='Coordinates in latitude, longitude format.'
className='w-80'
registerOptions={AREA_LATLNG_FORM_VALIDATION_RULES}
/>
{isLeaf
? (<DashboardInput
name='latlngStr'
label='Coordinates in latitude, longitude format.'
className='w-80'
registerOptions={AREA_LATLNG_FORM_VALIDATION_RULES}
readOnly={!isLeaf}
/>)
: (<p className='text-secondary'>Coordinates field available only when area type is either 'Crag' or 'Boulder'.</p>)}
</SingleEntryForm>
)
}
2 changes: 1 addition & 1 deletion src/app/(default)/editArea/[slug]/general/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default async function AreaEditPage ({ params }: DashboardPageProps): Pro
</SectionContainer>

<SectionContainer id='location'>
<AreaLatLngForm initLat={lat} initLng={lng} uuid={uuid} />
<AreaLatLngForm initLat={lat} initLng={lng} uuid={uuid} isLeaf={leaf} />
</SectionContainer>

<SectionContainer id='areaType'>
Expand Down
14 changes: 11 additions & 3 deletions src/app/(default)/editArea/[slug]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ArrowUUpLeft } from '@phosphor-icons/react/dist/ssr'
import { SidebarNav } from './SidebarNav'
import { SidebarNav } from './components/SidebarNav'
import { getPageDataForEdit } from './general/page'
import { AreaCrumbs } from '@/components/breadcrumbs/AreaCrumbs'
import { getAreaPageFriendlyUrl } from '@/js/utils'
Expand All @@ -16,7 +16,7 @@ export default async function EditAreaDashboardLayout ({
children: React.ReactNode
params: { slug: string }
}): Promise<any> {
const { area: { uuid, pathTokens, ancestors, areaName, metadata: { leaf } } } = await getPageDataForEdit(params.slug)
const { area: { uuid, pathTokens, ancestors, areaName, children: subAreas, climbs, metadata: { leaf, isBoulder } } } = await getPageDataForEdit(params.slug)
return (
<div className='relative w-full h-full'>
<div className='px-12 pt-8 pb-4'>
Expand All @@ -34,7 +34,15 @@ export default async function EditAreaDashboardLayout ({
<AreaCrumbs pathTokens={pathTokens} ancestors={ancestors} editMode />
</div>
<div className='flex bg-base-200 flex-col lg:flex-row py-12'>
<SidebarNav slug={params.slug} canAddAreas={!leaf} canAddClimbs={leaf} />
<SidebarNav
slug={params.slug}
canAddAreas={!leaf}
canAddClimbs={leaf}
areaCount={subAreas.length}
climbCount={climbs.length}
isLeaf={leaf}
isBoulder={isBoulder}
/>
<main className='relative h-full w-full px-2 lg:px-16'>
{children}
</main>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/form/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const BaseInput: React.FC<BaseInputProps> = ({ label, name, placeholder =
{...inputProps}
type={type}
placeholder={placeholder}
className={clx(classDefault, className)}
className={clx(classDefault, className, readOnly && 'cursor-not-allowed bg-base-200 focus:ring-0')}
aria-label={label}
aria-describedby={`${name}-helper`}
disabled={disabled}
Expand Down
Loading