From 5a797f0d14544730433ffd50c647770c3f369a50 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 16 Nov 2022 05:47:30 -0800 Subject: [PATCH] Fix party details * Populate from SSR * Hide button to edit empty anonymous grids --- components/Party/index.tsx | 5 + components/PartyDetails/index.tsx | 585 ++++++++++++++++-------------- types/Party.d.ts | 1 + 3 files changed, 313 insertions(+), 278 deletions(-) diff --git a/components/Party/index.tsx b/components/Party/index.tsx index c01f6829..2530de64 100644 --- a/components/Party/index.tsx +++ b/components/Party/index.tsx @@ -156,6 +156,11 @@ const Party = (props: Props) => { // Methods: Storing party data const storeParty = function (party: Party) { // Store the important party and state-keeping values + appState.party.name = party.name + appState.party.description = party.description + appState.party.raid = party.raid + appState.party.updated_at = party.updated_at + appState.party.id = party.id appState.party.extra = party.extra appState.party.user = party.user diff --git a/components/PartyDetails/index.tsx b/components/PartyDetails/index.tsx index 80884616..374ddb93 100644 --- a/components/PartyDetails/index.tsx +++ b/components/PartyDetails/index.tsx @@ -1,317 +1,346 @@ -import React, { useState } from 'react' -import Head from 'next/head' -import { useRouter } from 'next/router' -import { useSnapshot } from 'valtio' -import { useTranslation } from 'next-i18next' +import React, { useState } from "react" +import Head from "next/head" +import { useRouter } from "next/router" +import { useSnapshot } from "valtio" +import { useTranslation } from "next-i18next" -import Linkify from 'react-linkify' -import classNames from 'classnames' +import Linkify from "react-linkify" +import classNames from "classnames" -import * as AlertDialog from '@radix-ui/react-alert-dialog' -import CrossIcon from '~public/icons/Cross.svg' +import * as AlertDialog from "@radix-ui/react-alert-dialog" +import CrossIcon from "~public/icons/Cross.svg" -import Button from '~components/Button' -import CharLimitedFieldset from '~components/CharLimitedFieldset' -import RaidDropdown from '~components/RaidDropdown' -import TextFieldset from '~components/TextFieldset' +import Button from "~components/Button" +import CharLimitedFieldset from "~components/CharLimitedFieldset" +import RaidDropdown from "~components/RaidDropdown" +import TextFieldset from "~components/TextFieldset" -import { accountState } from '~utils/accountState' -import { appState } from '~utils/appState' +import { accountState } from "~utils/accountState" +import { appState } from "~utils/appState" -import './index.scss' -import Link from 'next/link' -import { formatTimeAgo } from '~utils/timeAgo' +import "./index.scss" +import Link from "next/link" +import { formatTimeAgo } from "~utils/timeAgo" const emptyRaid: Raid = { - id: '', - name: { - en: '', - ja: '' - }, - slug: '', - level: 0, - group: 0, - element: 0 + id: "", + name: { + en: "", + ja: "", + }, + slug: "", + level: 0, + group: 0, + element: 0, } // Props interface Props { - editable: boolean - updateCallback: (name?: string, description?: string, raid?: Raid) => void - deleteCallback: (event: React.MouseEvent) => void + editable: boolean + updateCallback: (name?: string, description?: string, raid?: Raid) => void + deleteCallback: ( + event: React.MouseEvent + ) => void } const PartyDetails = (props: Props) => { - const { party, raids } = useSnapshot(appState) - const { account } = useSnapshot(accountState) + const { party, raids } = useSnapshot(appState) + const { account } = useSnapshot(accountState) - const { t } = useTranslation('common') - const router = useRouter() - const locale = router.locale || 'en' + const { t } = useTranslation("common") + const router = useRouter() + const locale = router.locale || "en" - const nameInput = React.createRef() - const descriptionInput = React.createRef() - const raidSelect = React.createRef() + const nameInput = React.createRef() + const descriptionInput = React.createRef() + const raidSelect = React.createRef() - const readOnlyClasses = classNames({ - 'PartyDetails': true, - 'ReadOnly': true, - 'Visible': !party.detailsVisible - }) + const readOnlyClasses = classNames({ + PartyDetails: true, + ReadOnly: true, + Visible: !party.detailsVisible, + }) - const editableClasses = classNames({ - 'PartyDetails': true, - 'Editable': true, - 'Visible': party.detailsVisible - }) + const editableClasses = classNames({ + PartyDetails: true, + Editable: true, + Visible: party.detailsVisible, + }) - const emptyClasses = classNames({ - 'EmptyDetails': true, - 'Visible': !party.detailsVisible - }) + const emptyClasses = classNames({ + EmptyDetails: true, + Visible: !party.detailsVisible, + }) - const userClass = classNames({ - 'user': true, - 'empty': !party.user - }) + const userClass = classNames({ + user: true, + empty: !party.user, + }) - const linkClass = classNames({ - 'wind': party && party.element == 1, - 'fire': party && party.element == 2, - 'water': party && party.element == 3, - 'earth': party && party.element == 4, - 'dark': party && party.element == 5, - 'light': party && party.element == 6 - }) + const linkClass = classNames({ + wind: party && party.element == 1, + fire: party && party.element == 2, + water: party && party.element == 3, + earth: party && party.element == 4, + dark: party && party.element == 5, + light: party && party.element == 6, + }) - const [errors, setErrors] = useState<{ [key: string]: string }>({ - name: '', - description: '' - }) + const [errors, setErrors] = useState<{ [key: string]: string }>({ + name: "", + description: "", + }) - function handleInputChange(event: React.ChangeEvent) { - event.preventDefault() + function handleInputChange(event: React.ChangeEvent) { + event.preventDefault() - const { name, value } = event.target - let newErrors = errors + const { name, value } = event.target + let newErrors = errors - setErrors(newErrors) - } + setErrors(newErrors) + } - function handleTextAreaChange(event: React.ChangeEvent) { - event.preventDefault() + function handleTextAreaChange(event: React.ChangeEvent) { + event.preventDefault() - const { name, value } = event.target - let newErrors = errors + const { name, value } = event.target + let newErrors = errors - setErrors(newErrors) - } + setErrors(newErrors) + } - function toggleDetails() { - appState.party.detailsVisible = !appState.party.detailsVisible - } + function toggleDetails() { + appState.party.detailsVisible = !appState.party.detailsVisible + } - function updateDetails(event: React.MouseEvent) { - const nameValue = nameInput.current?.value - const descriptionValue = descriptionInput.current?.value - const raid = raids.find(raid => raid.slug === raidSelect.current?.value) + function updateDetails(event: React.MouseEvent) { + const nameValue = nameInput.current?.value + const descriptionValue = descriptionInput.current?.value + const raid = raids.find((raid) => raid.slug === raidSelect.current?.value) - props.updateCallback(nameValue, descriptionValue, raid) - toggleDetails() - } + props.updateCallback(nameValue, descriptionValue, raid) + toggleDetails() + } - const userImage = () => { - if (party.user) - return ( - {party.user.picture.picture} { + if (party.user) + return ( + {party.user.picture.picture} - ) - else - return (
) - } - - const userBlock = () => { - return ( -
- { userImage() } - { (party.user) ? party.user.username : t('no_user') } -
- ) - } - - const linkedUserBlock = (user: User) => { - return ( -
- - {userBlock()} - -
- ) - } - - const linkedRaidBlock = (raid: Raid) => { - return ( - - ) - } - - const deleteButton = () => { - if (party.editable) { - return ( - - - - - - {t('buttons.delete')} - - - - - - {t('modals.delete_team.title')} - - - {t('modals.delete_team.description')} - -
- {t('modals.delete_team.buttons.cancel')} - props.deleteCallback(e)}>{t('modals.delete_team.buttons.confirm')} -
-
-
-
- ) - } else { - return ('') - } - } - - const editable = ( -
- - - - -
-
- { (router.pathname !== '/new') ? deleteButton() : '' } -
-
- - - -
-
-
- ) - - const readOnly = ( -
-
-
- { (party.name) ?

{party.name}

: '' } -
- { (party.user) ? linkedUserBlock(party.user) : userBlock() } - { (party.raid) ? linkedRaidBlock(party.raid) : '' } - { (party.created_at != undefined) - ? - : '' } -
-
-
- { (party.editable) - ? - :
} -
-
- { (party.description) ?

{party.description}

: '' } -
- ) - - const emptyDetails = ( -
- -
- ) - - const generateTitle = () => { - let title = '' - - const username = (party.user != null) ? `@${party.user?.username}` : 'Anonymous' - - if (party.name != null) - title = `${party.name} by ${username}` - else if (party.name == null && party.editable && router.route === '/new') - title = "New Team" - else - title = `Untitled team by ${username}` - - return title - } + src={`/profile/${party.user.picture.picture}.png`} + /> + ) + else return
+ } + const userBlock = () => { return ( -
- - {generateTitle()} - - - - - - - - - - - - { (editable && (party.name || party.description || party.raid)) ? readOnly : emptyDetails} - {editable} -
+
+ {userImage()} + {party.user ? party.user.username : t("no_user")} +
) + } + + const linkedUserBlock = (user: User) => { + return ( +
+ + {userBlock()} + +
+ ) + } + + const linkedRaidBlock = (raid: Raid) => { + return ( + + ) + } + + const deleteButton = () => { + if (party.editable) { + return ( + + + + + + {t("buttons.delete")} + + + + + + {t("modals.delete_team.title")} + + + {t("modals.delete_team.description")} + +
+ + {t("modals.delete_team.buttons.cancel")} + + props.deleteCallback(e)} + > + {t("modals.delete_team.buttons.confirm")} + +
+
+
+
+ ) + } else { + return "" + } + } + + const editable = ( +
+ + + + +
+
+ {router.pathname !== "/new" ? deleteButton() : ""} +
+
+ + + +
+
+
+ ) + + const readOnly = ( +
+
+
+ {party.name ?

{party.name}

: ""} +
+ {party.user ? linkedUserBlock(party.user) : userBlock()} + {party.raid ? linkedRaidBlock(party.raid) : ""} + {party.created_at != undefined ? ( + + ) : ( + "" + )} +
+
+
+ {party.editable ? ( + + ) : ( +
+ )} +
+
+ {party.description ? ( +

+ {party.description} +

+ ) : ( + "" + )} +
+ ) + + const emptyDetails = ( +
+ {party.editable ? ( + + ) : ( +
+ )} +
+ ) + + const generateTitle = () => { + let title = "" + + const username = + party.user != null ? `@${party.user?.username}` : "Anonymous" + + if (party.name != null) title = `${party.name} by ${username}` + else if (party.name == null && party.editable && router.route === "/new") + title = "New Team" + else title = `Untitled team by ${username}` + + return title + } + + return ( +
+ + {generateTitle()} + + + + + + + + + + + + {editable && (party.name || party.description || party.raid) + ? readOnly + : emptyDetails} + {editable} +
+ ) } export default PartyDetails diff --git a/types/Party.d.ts b/types/Party.d.ts index 97d91c86..5a1dea6b 100644 --- a/types/Party.d.ts +++ b/types/Party.d.ts @@ -1,6 +1,7 @@ interface Party { id: string name: string + description: string raid: Raid shortcode: string extra: boolean