From c793fdb6a9294f8cb248cafb911eca27f6bc701c Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 19 Apr 2023 00:36:32 -0700 Subject: [PATCH] Implement searching for/adding guidebooks to party --- components/extra/GuidebookResult/index.scss | 37 ++++++++++++++++++ components/extra/GuidebookResult/index.tsx | 32 +++++++++++++++ components/party/Party/index.tsx | 33 ++++++++++++---- components/search/SearchModal/index.scss | 5 +++ components/search/SearchModal/index.tsx | 43 +++++++++++++++++++-- components/weapon/WeaponGrid/index.tsx | 7 ++++ 6 files changed, 147 insertions(+), 10 deletions(-) create mode 100644 components/extra/GuidebookResult/index.scss create mode 100644 components/extra/GuidebookResult/index.tsx diff --git a/components/extra/GuidebookResult/index.scss b/components/extra/GuidebookResult/index.scss new file mode 100644 index 00000000..368e3140 --- /dev/null +++ b/components/extra/GuidebookResult/index.scss @@ -0,0 +1,37 @@ +.GuidebookResult { + border-radius: 6px; + display: flex; + gap: $unit; + padding: $unit * 1.5; + + &:hover { + background: var(--button-contained-bg); + cursor: pointer; + + .Info h5 { + color: var(--text-primary); + } + } + + img { + background: $grey-80; + border-radius: 6px; + display: inline-block; + height: auto; + width: 90px; + } + + .Info { + display: flex; + flex-direction: column; + flex-grow: 1; + gap: $unit-half; + + h5 { + color: var(--text-tertiary); + display: inline-block; + font-size: $font-medium; + font-weight: $medium; + } + } +} diff --git a/components/extra/GuidebookResult/index.tsx b/components/extra/GuidebookResult/index.tsx new file mode 100644 index 00000000..4c84c5d7 --- /dev/null +++ b/components/extra/GuidebookResult/index.tsx @@ -0,0 +1,32 @@ +import React from 'react' +import { useRouter } from 'next/router' + +import './index.scss' + +interface Props { + data: Guidebook + onClick: () => void +} + +const GuidebookResult = (props: Props) => { + const router = useRouter() + const locale = + router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en' + + const guidebook = props.data + + return ( +
  • + {guidebook.name[locale]} +
    +
    {guidebook.name[locale]}
    +

    {guidebook.description[locale]}

    +
    +
  • + ) +} + +export default GuidebookResult diff --git a/components/party/Party/index.tsx b/components/party/Party/index.tsx index 6937a9e4..1376a432 100644 --- a/components/party/Party/index.tsx +++ b/components/party/Party/index.tsx @@ -22,9 +22,6 @@ import type { DetailsObject } from '~types' import './index.scss' -import WeaponRep from '~components/reps/WeaponRep' -import CharacterRep from '~components/reps/CharacterRep' -import SummonRep from '~components/reps/SummonRep' import PartyHeader from '../PartyHeader' // Props @@ -139,8 +136,11 @@ const Party = (props: Props) => { if (details.turnCount) payload.turn_count = details.turnCount if (details.extra) payload.extra = details.extra if (details.job) payload.job_id = details.job.id + if (details.guidebook0_id) payload.guidebook0_id = details.guidebook0_id + if (details.guidebook1_id) payload.guidebook1_id = details.guidebook1_id + if (details.guidebook2_id) payload.guidebook2_id = details.guidebook2_id - if (Object.keys(payload).length > 1) return { party: payload } + if (Object.keys(payload).length >= 1) return { party: payload } else return {} } @@ -154,17 +154,31 @@ const Party = (props: Props) => { } } - function checkboxChanged(event: React.ChangeEvent) { - appState.party.extra = event.target.checked + function checkboxChanged(enabled: boolean) { + appState.party.extra = enabled // Only save if this is a saved party if (props.team && props.team.id) { api.endpoints.parties.update(props.team.id, { - party: { extra: event.target.checked }, + party: { extra: enabled }, }) } } + function updateGuidebook(book: Guidebook, position: number) { + const details: DetailsObject = { + guidebook0_id: position === 0 ? book.id : undefined, + guidebook1_id: position === 1 ? book.id : undefined, + guidebook2_id: position === 2 ? book.id : undefined, + } + + if (props.team && props.team.id) { + updateParty(details) + } else { + createParty(details) + } + } + // Remixing the party function remixTeam() { // setOriginalName(partySnapshot.name ? partySnapshot.name : t('no_title')) @@ -230,6 +244,7 @@ const Party = (props: Props) => { appState.party.id = team.id appState.party.shortcode = team.shortcode appState.party.extra = team.extra + appState.party.guidebooks = team.guidebooks appState.party.user = team.user appState.party.favorited = team.favorited appState.party.remix = team.remix @@ -334,8 +349,11 @@ const Party = (props: Props) => { new={props.new || false} editable={editable} weapons={props.team?.weapons} + guidebooks={props.team?.guidebooks} createParty={createParty} pushHistory={props.pushHistory} + updateExtra={checkboxChanged} + updateGuidebook={updateGuidebook} /> ) @@ -384,6 +402,7 @@ const Party = (props: Props) => { {navigation}
    {currentGrid()}
    + { @@ -184,7 +185,7 @@ const SearchModal = (props: Props) => { } else if (open && currentPage == 1) { fetchResults({ replace: true }) } - }, [currentPage]) + }, [open, currentPage]) useEffect(() => { // Filters changed @@ -219,6 +220,17 @@ const SearchModal = (props: Props) => { } }, [query]) + useEffect(() => { + if (open && props.object === 'guidebooks') { + setCurrentPage(1) + fetchResults({ replace: true }) + } + }, [query, open]) + + function incrementPage() { + setCurrentPage(currentPage + 1) + } + function renderResults() { let jsx @@ -235,12 +247,15 @@ const SearchModal = (props: Props) => { case 'job_skills': jsx = renderJobSkillSearchResults(results) break + case 'guidebooks': + jsx = renderGuidebookSearchResults(results) + break } return ( 0 ? results.length : 0} - next={() => setCurrentPage(currentPage + 1)} + next={incrementPage} hasMore={totalPages > currentPage} scrollableTarget="Results" loader={
    Loading...
    } @@ -334,6 +349,27 @@ const SearchModal = (props: Props) => { return jsx } + function renderGuidebookSearchResults(results: { [key: string]: any }) { + let jsx: React.ReactNode + + const castResults: Guidebook[] = results as Guidebook[] + if (castResults && Object.keys(castResults).length > 0) { + jsx = castResults.map((result: Guidebook) => { + return ( + { + storeRecentResult(result) + }} + /> + ) + }) + } + + return jsx + } + function openChange() { if (open) { setQuery('') @@ -365,6 +401,7 @@ const SearchModal = (props: Props) => { diff --git a/components/weapon/WeaponGrid/index.tsx b/components/weapon/WeaponGrid/index.tsx index e0e3c433..4dcfd9dc 100644 --- a/components/weapon/WeaponGrid/index.tsx +++ b/components/weapon/WeaponGrid/index.tsx @@ -121,6 +121,13 @@ const WeaponGrid = (props: Props) => { } } + function receiveGuidebookFromSearch( + object: SearchableObject, + position: number + ) { + props.updateGuidebook(object as Guidebook, position) + } + async function handleWeaponResponse(data: any) { if (data.hasOwnProperty('conflicts')) { if (data.incoming) setIncoming(data.incoming)