Collection fixes (#416)

This fixes some issues that cropped up in the last PR

---------

Co-authored-by: Justin Edmund <383021+jedmund@users.noreply.github.com>
This commit is contained in:
Justin Edmund 2024-04-22 23:57:49 -07:00 committed by GitHub
parent 2eaaf1baae
commit 4a38168593
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 123 additions and 136 deletions

View file

@ -16,6 +16,7 @@
width: 100%; width: 100%;
max-width: 996px; max-width: 996px;
min-height: 80px; min-height: 80px;
z-index: 999;
@include breakpoint(tablet) { @include breakpoint(tablet) {
position: static; position: static;

View file

@ -3,11 +3,8 @@
border: 1px solid transparent; border: 1px solid transparent;
border-radius: $card-corner; border-radius: $card-corner;
box-sizing: border-box; box-sizing: border-box;
display: grid;
grid-template-rows: 1fr 1fr;
gap: $unit;
padding: $unit-2x $unit-2x 0 $unit-2x;
min-width: 320px; min-width: 320px;
position: relative;
width: 100%; width: 100%;
opacity: 1; opacity: 1;
@ -54,6 +51,22 @@
} }
} }
a {
display: grid;
grid-template-rows: auto 1fr;
grid-gap: 8px;
gap: 8px;
padding: $unit-2x $unit-2x 0 $unit-2x;
}
button {
position: absolute;
z-index: 2;
right: $unit-2x;
top: $unit-2x;
width: 44px;
}
.gridContainer { .gridContainer {
aspect-ratio: 2/0.95; aspect-ratio: 2/0.95;
width: 100%; width: 100%;
@ -118,9 +131,9 @@
} }
.weaponGrid { .weaponGrid {
aspect-ratio: 2/0.95; aspect-ratio: 2/0.8;
display: grid; display: grid;
grid-template-columns: 1fr 3.36fr; /* left column takes up 1 fraction, right column takes up 3 fractions */ grid-template-columns: 1fr 3.6fr; /* left column takes up 1 fraction, right column takes up 3 fractions */
grid-gap: $unit; /* add a gap of 8px between grid items */ grid-gap: $unit; /* add a gap of 8px between grid items */
.weapon { .weapon {

View file

@ -501,19 +501,17 @@ const GridRep = ({ party, loading, onClick, onSave }: Props) => {
) )
const favoriteButton = ( const favoriteButton = (
<Link href="#"> <Button
<Button className={classNames({
className={classNames({ save: true,
save: true, saved: party.favorited,
saved: party.favorited, })}
})} leftAccessoryIcon={<SaveIcon className="stroke" />}
leftAccessoryIcon={<SaveIcon className="stroke" />} active={party.favorited}
active={party.favorited} bound={true}
bound={true} size="small"
size="small" onClick={sendSaveData}
onClick={sendSaveData} />
/>
</Link>
) )
const renderFavoriteButton = const renderFavoriteButton =
@ -563,11 +561,12 @@ const GridRep = ({ party, loading, onClick, onSave }: Props) => {
)} )}
</div> </div>
</div> </div>
<div className={styles.buttonArea}> {[2, 3].includes(party.visibility) && (
{renderPrivateIcon} <div className={styles.buttonArea}>
{renderVisibilityIcon} {renderPrivateIcon}
{renderFavoriteButton} {renderVisibilityIcon}
</div> </div>
)}
</div> </div>
<div className={styles.attributed}> <div className={styles.attributed}>
{attribution()} {attribution()}
@ -587,49 +586,51 @@ const GridRep = ({ party, loading, onClick, onSave }: Props) => {
} }
return ( return (
<Link <div className={gridRepClasses}>
href={`/p/${party.shortcode}`} {renderFavoriteButton}
className={gridRepClasses} <Link
onMouseLeave={() => changeView('weapons')} href={`/p/${party.shortcode}`}
> onMouseLeave={() => changeView('weapons')}
{detailsWithUsername} >
<div className={styles.gridContainer}> {detailsWithUsername}
{currentView === 'characters' <div className={styles.gridContainer}>
? renderCharacterGrid {currentView === 'characters'
: currentView === 'summons' ? renderCharacterGrid
? renderSummonGrid : currentView === 'summons'
: renderWeaponGrid} ? renderSummonGrid
</div> : renderWeaponGrid}
<ul className={styles.indicators}> </div>
<li <ul className={styles.indicators}>
className={classNames({ <li
[styles.active]: currentView === 'characters', className={classNames({
})} [styles.active]: currentView === 'characters',
onMouseEnter={() => changeView('characters')} })}
> onMouseEnter={() => changeView('characters')}
<div className={styles.indicator} /> >
<span>Characters</span> <div className={styles.indicator} />
</li> <span>Characters</span>
<li </li>
className={classNames({ <li
[styles.active]: currentView === 'weapons', className={classNames({
})} [styles.active]: currentView === 'weapons',
onMouseEnter={() => changeView('weapons')} })}
> onMouseEnter={() => changeView('weapons')}
<div className={styles.indicator} /> >
<span>Weapons</span> <div className={styles.indicator} />
</li> <span>Weapons</span>
<li </li>
className={classNames({ <li
[styles.active]: currentView === 'summons', className={classNames({
})} [styles.active]: currentView === 'summons',
onMouseEnter={() => changeView('summons')} })}
> onMouseEnter={() => changeView('summons')}
<div className={styles.indicator} /> >
<span>Summons</span> <div className={styles.indicator} />
</li> <span>Summons</span>
</ul> </li>
</Link> </ul>
</Link>
</div>
) )
} }

View file

@ -171,7 +171,7 @@ export const useTeamFilter = (
isFetching, isFetching,
setFetching, setFetching,
fetchError, fetchError,
fetchTeams, fetch,
processTeams, processTeams,
currentPage, currentPage,
setCurrentPage, setCurrentPage,

View file

@ -8,19 +8,16 @@ import InfiniteScroll from 'react-infinite-scroll-component'
// Hooks // Hooks
import { useFavorites } from '~hooks/useFavorites' import { useFavorites } from '~hooks/useFavorites'
import { useTeamFilter } from '~hooks/useTeamFilter' import { useTeamFilter } from '~hooks/useTeamFilter'
import useDidMountEffect from '~hooks/useDidMountEffect'
// Utils // Utils
import fetchLatestVersion from '~utils/fetchLatestVersion' import fetchLatestVersion from '~utils/fetchLatestVersion'
import { appState } from '~utils/appState' import { appState } from '~utils/appState'
import { convertAdvancedFilters } from '~utils/convertAdvancedFilters'
import { CollectionPage } from '~utils/enums' import { CollectionPage } from '~utils/enums'
import { permissiveFilterset } from '~utils/defaultFilters' import { permissiveFilterset } from '~utils/defaultFilters'
import { setHeaders } from '~utils/userToken' import { setHeaders } from '~utils/userToken'
import { import {
fetchRaidGroupsAndFilters, fetchRaidGroupsAndFilters,
fetchUserProfile, fetchUserProfile,
parseAdvancedFilters,
} from '~utils/serverSideUtils' } from '~utils/serverSideUtils'
// Types // Types
@ -77,7 +74,7 @@ const ProfileRoute: React.FC<Props> = ({
isFetching, isFetching,
setFetching, setFetching,
fetchError, fetchError,
fetchTeams, fetch,
processTeams, processTeams,
setPagination, setPagination,
} = useTeamFilter(CollectionPage.Profile, context) } = useTeamFilter(CollectionPage.Profile, context)
@ -85,20 +82,17 @@ const ProfileRoute: React.FC<Props> = ({
const { toggleFavorite } = useFavorites(parties, setParties) const { toggleFavorite } = useFavorites(parties, setParties)
// Set the initial parties from props // Set the initial parties from props
useDidMountEffect(() => { useEffect(() => {
if (context) { if (context) {
if (context.teams && context.pagination) { fetch(true)
processTeams(context.teams, true)
setPagination(context.pagination)
appState.raidGroups = context.raidGroups appState.raidGroups = context.raidGroups
appState.version = version appState.version = version
}
} }
setCurrentPage(1) setCurrentPage(1)
setFetching(false) setFetching(false)
}, [context]) }, [])
// Fetch all raids on mount, then find the raid in the URL if present // Fetch all raids on mount, then find the raid in the URL if present
useEffect(() => { useEffect(() => {
@ -230,16 +224,11 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
// Perform a request only if we received a username // Perform a request only if we received a username
if (query.username) { if (query.username) {
const { user, teams, pagination } = await fetchUserProfile( const { user } = await fetchUserProfile(query.username, {})
query.username,
filters
)
context = { context = {
user: user, user: user,
teams: teams,
raidGroups: raidGroups, raidGroups: raidGroups,
pagination: pagination,
} }
} }

View file

@ -8,20 +8,14 @@ import InfiniteScroll from 'react-infinite-scroll-component'
// Hooks // Hooks
import { useFavorites } from '~hooks/useFavorites' import { useFavorites } from '~hooks/useFavorites'
import { useTeamFilter } from '~hooks/useTeamFilter' import { useTeamFilter } from '~hooks/useTeamFilter'
import useDidMountEffect from '~hooks/useDidMountEffect'
// Utils // Utils
import fetchLatestVersion from '~utils/fetchLatestVersion' import fetchLatestVersion from '~utils/fetchLatestVersion'
import { appState } from '~utils/appState' import { appState } from '~utils/appState'
import { convertAdvancedFilters } from '~utils/convertAdvancedFilters'
import { CollectionPage } from '~utils/enums' import { CollectionPage } from '~utils/enums'
import { permissiveFilterset } from '~utils/defaultFilters' import { permissiveFilterset } from '~utils/defaultFilters'
import { setHeaders } from '~utils/userToken' import { setHeaders } from '~utils/userToken'
import { import { fetchRaidGroups } from '~utils/serverSideUtils'
fetchRaidGroupsAndFilters,
fetchSaved,
parseAdvancedFilters,
} from '~utils/serverSideUtils'
// Types // Types
import type { AxiosError } from 'axios' import type { AxiosError } from 'axios'
@ -75,7 +69,7 @@ const SavedRoute: React.FC<Props> = ({
isFetching, isFetching,
setFetching, setFetching,
fetchError, fetchError,
fetchTeams, fetch,
processTeams, processTeams,
setPagination, setPagination,
} = useTeamFilter(CollectionPage.Saved, context) } = useTeamFilter(CollectionPage.Saved, context)
@ -83,20 +77,17 @@ const SavedRoute: React.FC<Props> = ({
const { toggleFavorite } = useFavorites(parties, setParties) const { toggleFavorite } = useFavorites(parties, setParties)
// Set the initial parties from props // Set the initial parties from props
useDidMountEffect(() => { useEffect(() => {
if (context) { if (context) {
if (context.teams && context.pagination) { fetch(true)
processTeams(context.teams, true)
setPagination(context.pagination)
appState.raidGroups = context.raidGroups appState.raidGroups = context.raidGroups
appState.version = version appState.version = version
}
} }
setCurrentPage(1) setCurrentPage(1)
setFetching(false) setFetching(false)
}, [context]) }, [])
// Fetch all raids on mount, then find the raid in the URL if present // Fetch all raids on mount, then find the raid in the URL if present
useEffect(() => { useEffect(() => {
@ -222,12 +213,11 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
try { try {
// We don't pre-load advanced filters here // We don't pre-load advanced filters here
const { raidGroups, filters } = await fetchRaidGroupsAndFilters(query) const raidGroups= await fetchRaidGroups()
const { teams, pagination } = await fetchSaved(filters)
return { return {
props: { props: {
context: { teams, raidGroups, pagination }, context: { raidGroups },
version, version,
error: false, error: false,
...(await serverSideTranslations(locale, ['common'])), ...(await serverSideTranslations(locale, ['common'])),

View file

@ -9,19 +9,13 @@ import InfiniteScroll from 'react-infinite-scroll-component'
// Hooks // Hooks
import { useFavorites } from '~hooks/useFavorites' import { useFavorites } from '~hooks/useFavorites'
import { useTeamFilter } from '~hooks/useTeamFilter' import { useTeamFilter } from '~hooks/useTeamFilter'
import useDidMountEffect from '~hooks/useDidMountEffect'
// Utils // Utils
import fetchLatestVersion from '~utils/fetchLatestVersion' import fetchLatestVersion from '~utils/fetchLatestVersion'
import { appState } from '~utils/appState' import { appState } from '~utils/appState'
import { convertAdvancedFilters } from '~utils/convertAdvancedFilters'
import { defaultFilterset } from '~utils/defaultFilters' import { defaultFilterset } from '~utils/defaultFilters'
import { setHeaders } from '~utils/userToken' import { setHeaders } from '~utils/userToken'
import { import { fetchRaidGroups } from '~utils/serverSideUtils'
fetchParties,
fetchRaidGroupsAndFilters,
parseAdvancedFilters,
} from '~utils/serverSideUtils'
// Types // Types
import type { NextApiRequest, NextApiResponse } from 'next' import type { NextApiRequest, NextApiResponse } from 'next'
@ -72,7 +66,7 @@ const TeamsRoute: React.FC<Props> = ({
isFetching, isFetching,
setFetching, setFetching,
fetchError, fetchError,
fetchTeams, fetch,
processTeams, processTeams,
setPagination, setPagination,
} = useTeamFilter(CollectionPage.Teams, context) } = useTeamFilter(CollectionPage.Teams, context)
@ -80,20 +74,17 @@ const TeamsRoute: React.FC<Props> = ({
const { toggleFavorite } = useFavorites(parties, setParties) const { toggleFavorite } = useFavorites(parties, setParties)
// Set the initial parties from props // Set the initial parties from props
useDidMountEffect(() => { useEffect(() => {
if (context) { if (context) {
if (context.teams && context.pagination) { fetch(true)
processTeams(context.teams, true)
setPagination(context.pagination)
appState.raidGroups = context.raidGroups appState.raidGroups = context.raidGroups
appState.version = version appState.version = version
}
} }
setCurrentPage(1) setCurrentPage(1)
setFetching(false) setFetching(false)
}, [context]) }, [])
// Fetch all raids on mount, then find the raid in the URL if present // Fetch all raids on mount, then find the raid in the URL if present
useEffect(() => { useEffect(() => {
@ -153,14 +144,17 @@ const TeamsRoute: React.FC<Props> = ({
} }
const renderInfiniteScroll = ( const renderInfiniteScroll = (
<InfiniteScroll <>
dataLength={parties && parties.length > 0 ? parties.length : 0} {parties.length === 0 && renderLoading(3)}
next={() => setCurrentPage(currentPage + 1)} <InfiniteScroll
hasMore={totalPages > currentPage} dataLength={parties && parties.length > 0 ? parties.length : 0}
loader={renderLoading(3)} next={() => setCurrentPage(currentPage + 1)}
> hasMore={totalPages > currentPage}
<GridRepCollection>{renderParties()}</GridRepCollection> loader={renderLoading(3)}
</InfiniteScroll> >
<GridRepCollection>{renderParties()}</GridRepCollection>
</InfiniteScroll>
</>
) )
if (context) { if (context) {
@ -205,16 +199,11 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
const version = await fetchLatestVersion() const version = await fetchLatestVersion()
try { try {
const advancedFilters = parseAdvancedFilters(req, res) const raidGroups = await fetchRaidGroups()
const convertedFilters = advancedFilters
? convertAdvancedFilters(advancedFilters)
: undefined
const { raidGroups, filters } = await fetchRaidGroupsAndFilters(query)
const { teams, pagination } = await fetchParties(filters, convertedFilters)
return { return {
props: { props: {
context: { teams, raidGroups, pagination }, context: { raidGroups },
version, version,
error: false, error: false,
...(await serverSideTranslations(locale, ['common'])), ...(await serverSideTranslations(locale, ['common'])),

View file

@ -23,6 +23,10 @@ export async function fetchRaidGroupsAndFilters(query: {
return { raidGroups, filters } return { raidGroups, filters }
} }
export async function fetchRaidGroups() {
return await api.raidGroups().then((response) => response.data)
}
// Fetch initial set of parties // Fetch initial set of parties
export async function fetchParties( export async function fetchParties(
filters: FilterObject, filters: FilterObject,