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: Restrict attemptType based on style selected for ticks #1260

Merged

Conversation

glassbead0
Copy link
Contributor

@glassbead0 glassbead0 commented Jan 24, 2025


name: Pull request
about: Create a pull request
title: 'Restrict tick Attempt Type'
labels: ''
assignees: ''


What type of PR is this?(check all applicable)

  • refactor
  • feature
  • bug fix
  • documentation
  • optimization
  • other

Description

Related Issues

Issue #411

What this PR achieves

  • add the "Tick the Route" button to the newer climbs page (it was previously only on the old page)
  • dynamically populate available attemptType based on chosen style
  • display attemptType in TickCard when viewing listed ticks
  • add subtle info icon with link to Wikipedia's Glossary of Climbing Terms
  • tinker with z values because the breadcrumb nav bar was overlapping the tick dialog
  • increase notes size slightly to accomodate for longer list of attempt styles in the dropdown.

Screenshots, recordings

Screenshot 2025-01-24 at 5 06 16 PM

Notes

this is closely tied to OpenBeta/openbeta-graphql#444. and is essentially the front-end version of the same restrictions.

One thing i could use help with:
Style and attemptType can be empty, but right now thats getting sent as a string with a space. I'd like them to be nullable, but was running into issues with that.

@@ -37,7 +38,10 @@ export default function TickCard ({ tickId, ticks, setTicks, dateClimbed, notes,
<p className='text-sm text-gray-500 mb-0'>{notes}</p>
</div>
<div className='flex flex-row'>
<p className='text-sm text-gray-500 pr-5'>{style}</p>
<div className='flex flex-col'>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This shows the attemptType on the tick card:
Screenshot 2025-01-25 at 6 30 44 PM

@@ -440,7 +440,7 @@ const ClimbData: React.FC<{

{!editMode && (
<div className='mt-8'>
<TickButton climbId={climbId} name={name} grade={gradesObj.toString()} />
<TickButton climbId={climbId} name={name} grade={gradesObj.toString()} climbType={{}} />
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe I should just remove this tick buttons, since this is the "old" page....

Copy link
Contributor

Choose a reason for hiding this comment

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

you can leave the button there until we delete the page

@@ -12,7 +12,7 @@ const TicksModal: React.FC<any> = ({ open, setOpen, setTicks, setOpenForm, climb
}
return (
<Transition.Root show={open} as={Fragment}>
<Dialog as='div' className='relative z-10' initialFocus={cancelButtonRef} onClose={setOpen}>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These z-values were needed so the breadcrumb nav bar didn't obscure the Tick modal.

<label htmlFor='attemptType' className='block text-sm font-medium text-gray-700'>
Attempt Type
</label>
<a href={climbingGlossaryLink} target='_blank' rel='noopener noreferrer' className='ml-2 text-gray-500 hover:text-gray-700' title='climbing terminology'>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The little info button is a link to Climbing Glossary.
Screenshot 2025-01-25 at 6 33 55 PM

Copy link
Contributor

Choose a reason for hiding this comment

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

@vnugent
Copy link
Contributor

vnugent commented Jan 26, 2025

Does this PR supersede #1259? As commented in #1259 the backend doesn't like empty string for attemptType. Maybe use 'N/A'?

@@ -7,6 +7,7 @@ import { graphqlClient } from '../../js/graphql/Client'
import { MUTATION_ADD_TICK } from '../../js/graphql/gql/fragments'
import ComboBox from '../ui/ComboBox'
import * as Yup from 'yup'
import { InformationCircleIcon } from '@heroicons/react/20/solid'
Copy link
Contributor

Choose a reason for hiding this comment

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

<label htmlFor='attemptType' className='block text-sm font-medium text-gray-700'>
Attempt Type
</label>
<a href={climbingGlossaryLink} target='_blank' rel='noopener noreferrer' className='ml-2 text-gray-500 hover:text-gray-700' title='climbing terminology'>
Copy link
Contributor

Choose a reason for hiding this comment

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

@@ -440,7 +440,7 @@ const ClimbData: React.FC<{

{!editMode && (
<div className='mt-8'>
<TickButton climbId={climbId} name={name} grade={gradesObj.toString()} />
<TickButton climbId={climbId} name={name} grade={gradesObj.toString()} climbType={{}} />
Copy link
Contributor

Choose a reason for hiding this comment

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

you can leave the button there until we delete the page

@glassbead0
Copy link
Contributor Author

Does this PR supersede #1259? As commented in #1259 the backend doesn't like empty string for attemptType. Maybe use 'N/A'?

It does not supersede it. #1259 deals with MP imports, and this one is all for the OB interface for adding ticks. I can certainly combine them, as they are related. I tend to like to combine related work into single PRs, but I also appreciate the value of separating things more granularly.

@@ -1,3 +1,4 @@
'use client'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was getting errors locally telling me to add this here. "You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. Learn more: https://nextjs.org/docs/getting-started/react-essentials"

I don't know if thats a local-only issue for me though.

Copy link
Contributor

Choose a reason for hiding this comment

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

We do want to address that error. Generally, we want to have as many server-side components as possible and add "use client" directive as escape hatch. Maybe don't introduce "hover" behavior as it only works on desktop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm happy to remove the hover functionality, but I don't think thats related to the 'use client' error.

Prior to my code changes, the TickButton relied on useState to determine if a route has been ticked by a user, so it knows whether to display Tick This Route or View Ticks on the button.

I'm not sure how to rewrite that functionality without useState, but i'm not at all an expert on Next.js.

I do see several other components that 'use client', so i'm not sure what the best solution is here.

if (aidable) { styles.push(...allStyles.filter(style => ['Aid'].includes(style.name))) }
if (soloable) { styles.push(...allStyles.filter(style => ['Solo'].includes(style.name))) }
if (styles.length === 0) { styles = [...allStyles] } // If a climb doesn't have a type, anything goes
styles.push({ id: 10, name: '\u00A0' })
Copy link
Contributor Author

Choose a reason for hiding this comment

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

FYI the '\u00A0' is the html encoded space character. this is to get the dropdown to show a blank option (and look nice). Down below, It handles this case and sends undefined to the backend, which gets handles correctly in this pr OpenBeta/openbeta-graphql#444


interface Props {
content: string | ReactNode
enabled?: boolean
children: JSX.Element | JSX.Element [] | null
className?: string
trigger?: 'click' | 'hover'
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe we default to click because hover isn't usable on web mobile

Copy link
Contributor Author

@glassbead0 glassbead0 Feb 5, 2025

Choose a reason for hiding this comment

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

i did set default to click below on line 16, but regardless you're right, hover won't work on mobile. that said, my change here doesn't change the behavior of any other tooltip, only this specific one (which i wanted as a hover, because when you click it, it opens a link in a new tab).

I know this is an unnecessary tooltip at all though, and 'm totally happy to remove it if you think thats better.

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's not introduce a new behavior for Tooltip, and keep it consistent with existing UX (onClick show a tip, include a clickable external link if needed)

tooltip

@@ -1,3 +1,4 @@
'use client'
Copy link
Contributor

Choose a reason for hiding this comment

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

We do want to address that error. Generally, we want to have as many server-side components as possible and add "use client" directive as escape hatch. Maybe don't introduce "hover" behavior as it only works on desktop.

* add the "Tick the Route" button to the newer
  climbs page (it was previously only on the old page)
* dynamically populate available attemptType
  based on chosen style
* display attemptType in TickCard when viewing listed ticks
* add subtle info icon with link to Wikipedia's
  Glossary of Climbing Terms
* tinker with z values because the breadcrumb nav
  bar was overlapping the tick dialog
* increase notes size slightly to accomodate for
  longer list of attempt styles in the dropdown.
* use phosphor icons
* use existing Tooltip
* add 'hover' option to Tooltip
* make front-end and back-end logic the same
* add Alpine option when creating routes

interface Props {
content: string | ReactNode
enabled?: boolean
children: JSX.Element | JSX.Element [] | null
className?: string
trigger?: 'click' | 'hover'
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's not introduce a new behavior for Tooltip, and keep it consistent with existing UX (onClick show a tip, include a clickable external link if needed)

tooltip

@glassbead0 glassbead0 force-pushed the restrict_attempt_type_for_ticks branch from af02ac0 to a3f1ad9 Compare February 5, 2025 05:18
@glassbead0 glassbead0 requested a review from vnugent February 5, 2025 05:23
@vnugent vnugent merged commit d4a00ad into OpenBeta:develop Feb 5, 2025
3 checks passed
@vnugent
Copy link
Contributor

vnugent commented Feb 5, 2025

@all-contributors add @glassbead0 for code and ideas

Copy link
Contributor

@vnugent

I've put up a pull request to add @glassbead0! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants