diff --git a/components/PartyDetails/index.scss b/components/PartyDetails/index.scss index abe4e39a..50f88ffb 100644 --- a/components/PartyDetails/index.scss +++ b/components/PartyDetails/index.scss @@ -31,6 +31,22 @@ width: 100%; } } + + .bottom { + display: flex; + flex-direction: row; + gap: $unit; + + .left { + flex-grow: 1; + } + + .right { + display: flex; + flex-direction: row; + gap: $unit; + } + } } &.ReadOnly { @@ -45,26 +61,8 @@ top: 0; } - h1 { - font-size: $font-xlarge; - font-weight: $normal; - text-align: left; - margin-bottom: $unit; - } - - a { - color: $blue; - - &:hover { - text-decoration: underline; - } - } - - .Raid { - color: $grey-50; - font-size: $font-regular; - font-weight: $medium; - margin-bottom: $unit * 2; + a:hover { + text-decoration: underline; } p { @@ -72,5 +70,84 @@ line-height: $font-regular * 1.2; white-space: pre-line; } + + + h1 { + font-size: $font-xlarge; + font-weight: $normal; + text-align: left; + margin-bottom: $unit; + } + + .info { + align-items: center; + display: flex; + flex-direction: row; + gap: $unit; + margin-bottom: $unit * 2; + + .left { + flex-grow: 1; + } + } + + .attribution { + align-items: center; + display: flex; + flex-direction: row; + + & > div { + align-items: center; + display: inline-flex; + font-size: $font-small; + height: 26px; + } + + time { + font-size: $font-small; + } + + & > *:not(:last-child):after { + content: " · "; + margin: 0 calc($unit / 2); + } + } + + .user { + align-items: center; + display: inline-flex; + gap: calc($unit / 2); + margin-top: 1px; + + img, .no-user { + $diameter: 24px; + + border-radius: calc($diameter / 2); + height: $diameter; + width: $diameter; + } + + img.gran { + background-color: #CEE7FE; + } + + img.djeeta { + background-color: #FFE1FE; + } + + .no-user { + background: $grey-80; + } + } + } +} + +.EmptyDetails { + display: none; + justify-content: center; + margin-bottom: $unit * 10; + + &.Visible { + display: flex; } } \ No newline at end of file diff --git a/components/PartyDetails/index.tsx b/components/PartyDetails/index.tsx index bc765ca7..4c24d3d9 100644 --- a/components/PartyDetails/index.tsx +++ b/components/PartyDetails/index.tsx @@ -1,27 +1,53 @@ import React, { useState } from 'react' import Head from 'next/head' -import Router, { useRouter } from 'next/router' +import { useRouter } from 'next/router' import { useSnapshot } from 'valtio' +import { useTranslation } from 'next-i18next' + 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 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 './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 +} // Props interface Props { 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 { t } = useTranslation('common') const router = useRouter() + const locale = router.locale || 'en' const nameInput = React.createRef() const descriptionInput = React.createRef() @@ -39,6 +65,25 @@ const PartyDetails = (props: Props) => { 'Visible': party.detailsVisible }) + const emptyClasses = classNames({ + 'EmptyDetails': true, + 'Visible': !party.detailsVisible + }) + + 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 [errors, setErrors] = useState<{ [key: string]: string }>({ name: '', description: '' @@ -62,12 +107,100 @@ const PartyDetails = (props: Props) => { setErrors(newErrors) } - function updateDetails(event: React.ChangeEvent) { + function toggleDetails() { + appState.party.detailsVisible = !appState.party.detailsVisible + + // if (appState.party.detailsVisible) + // scroll.scrollToBottom() + // else + // scroll.scrollToTop() + } + + 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() + } + + const userImage = () => { + 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 ( +
+ + + {raid.name[locale]} + + +
+ ) + } + + 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 = ( @@ -77,7 +210,6 @@ const PartyDetails = (props: Props) => { placeholder="Name your team" value={party.name} limit={50} - onBlur={updateDetails} onChange={handleInputChange} error={errors.name} ref={nameInput} @@ -85,29 +217,72 @@ const PartyDetails = (props: Props) => { + +
+
+ { (router.pathname !== '/new') ? deleteButton() : '' } +
+
+ + + +
+
) const readOnly = (
- { (party.name) ?

{party.name}

: '' } - { (party.raid) ?
{party.raid.name.en}
: '' } +
+
+ { (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 = '' @@ -138,7 +313,7 @@ const PartyDetails = (props: Props) => { - {readOnly} + { (editable && (party.name || party.description || party.raid)) ? readOnly : emptyDetails} {editable}
)