Skip to content

Commit

Permalink
Add term details for HRAO and Rome Consul (#290)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamlogand authored Oct 3, 2023
1 parent 26b5fb4 commit 23ccbef
Show file tree
Hide file tree
Showing 26 changed files with 227 additions and 213 deletions.
6 changes: 3 additions & 3 deletions frontend/components/FactionIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styles from "./FactionIcon.module.css"
import Faction from '@/classes/Faction'
import SelectedEntity from "@/types/selectedEntity"
import SelectedDetail from "@/types/selectedDetail"
import { useGameContext } from "@/contexts/GameContext"

interface FactionIconProps {
Expand All @@ -11,10 +11,10 @@ interface FactionIconProps {

// Small flag icon representing a faction, identifiable by color
const FactionIcon = (props: FactionIconProps) => {
const { setSelectedEntity } = useGameContext()
const { setSelectedDetail } = useGameContext()

const handleClick = () => {
if (props.faction?.id) setSelectedEntity({className: "Faction", id: props.faction.id} as SelectedEntity)
if (props.faction?.id) setSelectedDetail({type: "Faction", id: props.faction.id} as SelectedDetail)
}

if (props.faction && props.faction) {
Expand Down
8 changes: 4 additions & 4 deletions frontend/components/FactionLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Link } from "@mui/material"

import { useGameContext } from '@/contexts/GameContext'
import Faction from "@/classes/Faction"
import SelectedEntity from "@/types/selectedEntity"
import SelectedDetail from "@/types/selectedDetail"
import FactionIcon from '@/components/FactionIcon'

interface FactionLinkProps {
Expand All @@ -11,14 +11,14 @@ interface FactionLinkProps {
}

const FactionLink = (props: FactionLinkProps) => {
const { setSelectedEntity } = useGameContext()
const { setSelectedDetail } = useGameContext()

const handleClick = () => {
if (props.faction) setSelectedEntity({className: "Faction", id: props.faction.id} as SelectedEntity)
if (props.faction) setSelectedDetail({type: "Faction", id: props.faction.id} as SelectedDetail)
}

return (
<Link component="button" onClick={handleClick} sx={{ verticalAlign: "baseline", userSelect: 'auto' }}>
<Link onClick={handleClick} sx={{ verticalAlign: "baseline", userSelect: 'auto', cursor: 'pointer' }}>
{props.includeIcon && <span style={{ marginRight: 4 }}><FactionIcon faction={props.faction} size={17} /></span>}
{props.faction.getName()} Faction
</Link>
Expand Down
4 changes: 2 additions & 2 deletions frontend/components/FactionListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ const FactionListItem = (props: FactionListItemProps) => {
const getAttributeItem = (item: Attribute) => {
const titleCaseName = item.name[0].toUpperCase() + item.name.slice(1)
return (
<Tooltip title={(item.sum ? 'Total' : '') + ` ${titleCaseName}`} enterDelay={500} arrow>
<div key={item.name} className={`${styles.attribute} ` + (!item.sum ? `${styles.nonSum}` : '')}>
<Tooltip key={item.name} title={(item.sum ? 'Total' : '') + ` ${titleCaseName}`} enterDelay={500} arrow>
<div className={`${styles.attribute} ` + (!item.sum ? `${styles.nonSum}` : '')}>
<div className={styles.symbols}>
{item.sum && <span className={styles.sigma}>Σ</span>}
<Image src={item.image} height={28} width={28} alt={`${titleCaseName} icon`} />
Expand Down
5 changes: 2 additions & 3 deletions frontend/components/MetaSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useEffect, useState } from 'react'
import Link from 'next/link'

import Button from '@mui/material/Button'
Expand All @@ -16,7 +15,7 @@ import Faction from '@/classes/Faction'
import Senator from '@/classes/Senator'
import FactionLink from '@/components/FactionLink'
import SenatorLink from '@/components/SenatorLink'
import { Tooltip } from '@mui/material'
import TermLink from '@/components/TermLink'


interface MetaSectionProps {
Expand Down Expand Up @@ -57,7 +56,7 @@ const MetaSection = (props: MetaSectionProps) => {
{hrao &&
<div>
<span>
The <Tooltip title="Highest Ranking Available Officer" enterDelay={500} arrow><span>HRAO</span></Tooltip> is <SenatorLink senator={hrao} />
The <TermLink name="HRAO" tooltipTitle='Highest Ranking Available Official' includeIcon /> is <SenatorLink senator={hrao} />
{hraoFaction && <span> of <FactionLink faction={hraoFaction} includeIcon /></span>}
</span>
</div>
Expand Down
8 changes: 4 additions & 4 deletions frontend/components/SenatorLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ import { Link } from "@mui/material"

import { useGameContext } from '@/contexts/GameContext'
import Senator from "@/classes/Senator"
import SelectedEntity from "@/types/selectedEntity"
import SelectedDetail from "@/types/selectedDetail"

interface SenatorLinkProps {
senator: Senator
}

const SenatorLink = (props: SenatorLinkProps) => {
const { setSelectedEntity } = useGameContext()
const { setSelectedDetail } = useGameContext()

const handleClick = () => {
if (props.senator) setSelectedEntity({className: "Senator", id: props.senator.id} as SelectedEntity)
if (props.senator) setSelectedDetail({type: "Senator", id: props.senator.id} as SelectedDetail)
}

return (
<Link component="button" onClick={handleClick} sx={{ verticalAlign: "baseline", userSelect: 'auto' }}>{props.senator.displayName}</Link>
<Link onClick={handleClick} sx={{ verticalAlign: "baseline", userSelect: 'auto', cursor: 'pointer' }}>{props.senator.displayName}</Link>
)
}

Expand Down
2 changes: 1 addition & 1 deletion frontend/components/SenatorPortrait.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
background-color: transparent;
}

.senatorPortrait figure {
.senatorPortrait>figure {
box-sizing: border-box;
background-color: var(--foreground-color);
border-radius: 4px;
Expand Down
10 changes: 5 additions & 5 deletions frontend/components/SenatorPortrait.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Faction from '@/classes/Faction'
import styles from "./SenatorPortrait.module.css"
import Title from '@/classes/Title'
import TitleIcon from '@/components/TitleIcon'
import SelectedEntity from "@/types/selectedEntity"
import SelectedDetail from "@/types/selectedDetail"
import Colors from "@/data/colors.json"
import FactionLeaderPattern from "@/images/patterns/factionLeader.svg"
import DeadIcon from "@/images/icons/dead.svg"
Expand Down Expand Up @@ -58,7 +58,7 @@ const senatorImages: { [key: string]: StaticImageData } = {
Quinctius: Quinctius,
Aemilius: Aemilius,
Terentius: Terentius,
};
}

interface SenatorPortraitProps {
senator: Senator
Expand All @@ -70,7 +70,7 @@ interface SenatorPortraitProps {
// The senator portrait is a visual representation of the senator,
// containing an image of their face, faction color background, and other status icons
const SenatorPortrait = ({ senator, size, ...props }: SenatorPortraitProps) => {
const { allFactions, allTitles, setSelectedEntity } = useGameContext()
const { allFactions, allTitles, setSelectedDetail } = useGameContext()

// Used to force a re-render when senator changes
const [key, setKey] = useState(0)
Expand Down Expand Up @@ -188,7 +188,7 @@ const SenatorPortrait = ({ senator, size, ...props }: SenatorPortraitProps) => {
setHover(false)
}
const handleClick = () => {
if (props.selectable) setSelectedEntity({className: "Senator", id: senator.id} as SelectedEntity)
if (props.selectable) setSelectedDetail({type: "Senator", id: senator.id} as SelectedDetail)
}

// Get JSX for the portrait
Expand Down Expand Up @@ -228,7 +228,7 @@ const SenatorPortrait = ({ senator, size, ...props }: SenatorPortraitProps) => {
}
{majorOffice && <TitleIcon title={majorOffice} size={getIconSize()} />}
{senator.alive === false &&
<Image src={DeadIcon} alt="Skull and crossbones icon" height={getIconSize()} className={styles.deadIcon} />
<Image src={DeadIcon} alt="Skull and crossbones icon" height={getIconSize()} width={getIconSize()} className={styles.deadIcon} />
}
</figure>
</PortraitElement>
Expand Down
6 changes: 6 additions & 0 deletions frontend/components/TermLink.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.icon {
margin-top: -5px;
vertical-align: middle;
user-select: none;
margin-right: 2px;
}
53 changes: 53 additions & 0 deletions frontend/components/TermLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import Image, { StaticImageData } from 'next/image'
import { Link } from "@mui/material"

import { Tooltip } from '@mui/material'
import HraoIcon from '@/images/icons/hrao.svg'
import RomeConsulIcon from '@/images/icons/romeConsul.svg'
import styles from './TermLink.module.css'
import { useGameContext } from '@/contexts/GameContext'
import SelectedDetail from '@/types/selectedDetail'

// Map of term names to images
const termImages: { [key: string]: StaticImageData } = {
"HRAO": HraoIcon,
"Rome Consul": RomeConsulIcon
}

interface TermLinkProps {
name: string,
displayName?: string,
tooltipTitle?: string,
includeIcon?: boolean
}

// Icon link for a game term
const TermLink = ({ name, displayName, tooltipTitle, includeIcon }: TermLinkProps) => {
const { setSelectedDetail } = useGameContext()

// Use the name to get the correct image
const getIcon = (): StaticImageData | string => {
if (termImages.hasOwnProperty(name)) return termImages[name]
else return ""
}

const handleClick = () => {
setSelectedDetail({type: "Term", name: name} as SelectedDetail)
}

// Get the JSX for the link
const getLink = () => (
<Link onClick={handleClick} sx={{ verticalAlign: "baseline", userSelect: 'auto', cursor: 'pointer' }}>
{includeIcon && <Image src={getIcon()} height={28} width={28} alt={`${name} Icon`} className={styles.icon} />}
{displayName ?? name}
</Link>
)

if (tooltipTitle) {
return <Tooltip title={tooltipTitle} enterDelay={500} arrow>{getLink()}</Tooltip>
} else {
return getLink()
}
}

export default TermLink
3 changes: 2 additions & 1 deletion frontend/components/actionLogs/ActionLog_FaceMortality.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import styles from "./ActionLog.module.css"
import Senator from '@/classes/Senator'
import SenatorLink from "@/components/SenatorLink"
import FactionLink from '@/components/FactionLink'
import TermLink from '@/components/TermLink'

interface NotificationProps {
notification: ActionLog
Expand Down Expand Up @@ -39,7 +40,7 @@ const FaceMortalityNotification = ({ notification, senatorDetails } : Notificati
return (
<p>
{majorOfficeName || heir ? <span>The</span> : null}
{majorOfficeName && <span> {majorOfficeName}</span>}
{majorOfficeName && <span> <TermLink name={majorOfficeName == "Temporary Rome Consul" ? "Rome Consul" : majorOfficeName} displayName={majorOfficeName} /></span>}
{majorOfficeName && heir ? <span> and</span> : null}
{heir && faction && <span> <FactionLink faction={faction} /> Leader</span>}
{majorOfficeName || heir ? <span>, </span> : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Faction from "@/classes/Faction"
import Senator from '@/classes/Senator'
import { useGameContext } from "@/contexts/GameContext"
import styles from "./ActionLog.module.css"
import TermLink from '@/components/TermLink'

interface NotificationProps {
notification: ActionLog
Expand All @@ -34,13 +35,13 @@ const TemporaryRomeConsulNotification = ({ notification, senatorDetails } : Noti
if (senatorDetails) {
return (
<p>
<SenatorLink senator={senator} /> became Temporary Rome Consul.
<SenatorLink senator={senator} /> became <TermLink name="Rome Consul" displayName="Temporary Rome Consul" />.
</p>
)
} else {
return (
<p>
<SenatorLink senator={senator} /> of the <FactionLink faction={faction} /> now holds the office of Temporary Rome Consul, making him the HRAO.
<SenatorLink senator={senator} /> of the <FactionLink faction={faction} /> now holds the office of <TermLink name="Rome Consul" displayName="Temporary Rome Consul" />, making him the <TermLink name="HRAO" />.
</p>
)
}
Expand Down
25 changes: 19 additions & 6 deletions frontend/components/detailSections/DetailSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,42 @@ import styles from "./DetailSection.module.css"
import SenatorDetailSection from '@/components/detailSections/DetailSection_Senator'
import FactionDetailSection from '@/components/detailSections/DetailSection_Faction'
import { useGameContext } from '@/contexts/GameContext'
import HraoTerm from '@/components/terms/Term_Hrao'
import RomeConsulTerm from '@/components/terms/Term_RomeConsul'

// Section showing details about selected entities
const DetailSection = () => {
const { selectedEntity, setSelectedEntity } = useGameContext()
const { selectedDetail, setSelectedDetail } = useGameContext()
const detailSectionRef = useRef<HTMLDivElement>(null);

if (!selectedEntity) return <div className={styles.nothing}><div>Nothing selected</div></div>
if (!selectedDetail) return <div className={styles.nothing}><div>Nothing selected</div></div>

// Get the component for the selected term
const getTermDetails = () => {
switch (selectedDetail.name) {
case "HRAO": return <HraoTerm />
case "Rome Consul": return <RomeConsulTerm />
}
}

return (
<div className={styles.detailSection}>
<div className={styles.header}>
<h3>Selected {selectedEntity?.className}</h3>
<Button onClick={() => setSelectedEntity(null)}>
<h3>Selected {selectedDetail.id ? selectedDetail.type : 'Term'}</h3>
<Button onClick={() => setSelectedDetail(null)}>
<FontAwesomeIcon icon={faXmark} fontSize={16} style={{marginRight: 8}} />Clear
</Button>
</div>
<div ref={detailSectionRef} className={styles.detailSectionInner}>
{ selectedEntity.className === "Senator" &&
{ selectedDetail.type === "Senator" &&
<SenatorDetailSection detailSectionRef={detailSectionRef} />
}
{ selectedEntity.className === "Faction" &&
{ selectedDetail.type === "Faction" &&
<FactionDetailSection />
}
{ selectedDetail.type === "Term" &&
getTermDetails()
}
</div>
</div>
)
Expand Down
10 changes: 5 additions & 5 deletions frontend/components/detailSections/DetailSection_Faction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import SenatorList from "@/components/SenatorList"

// Detail section content for a faction
const FactionDetails = () => {
const { allPlayers, allFactions, allSenators, selectedEntity } = useGameContext()
const { allPlayers, allFactions, allSenators, selectedDetail } = useGameContext()

// Get faction-specific data
let senators: Collection<Senator> = new Collection<Senator>([])
if (selectedEntity && selectedEntity.className == "Faction") {
senators = new Collection<Senator>(allSenators.asArray.filter(s => s.faction === selectedEntity.id))
if (selectedDetail && selectedDetail.type == "Faction") {
senators = new Collection<Senator>(allSenators.asArray.filter(s => s.faction === selectedDetail.id))
}
const faction: Faction | null = selectedEntity?.id ? allFactions.byId[selectedEntity.id] ?? null : null
const faction: Faction | null = selectedDetail?.id ? allFactions.byId[selectedDetail.id] ?? null : null
const player: Player | null = faction?.player ? allPlayers.byId[faction.player] ?? null : null

// If there is no faction selected, render nothing
Expand All @@ -29,7 +29,7 @@ const FactionDetails = () => {
<span className={styles.factionIcon}>
<FactionIcon faction={faction} size={26} />
</span>
<p><b>{faction.getName()} Faction</b> of {player.user?.username}</p>
<h4><b>{faction.getName()} Faction</b> of {player.user?.username}</h4>
</div>
<p>
This faction has {senators.allIds.length} aligned senators
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
margin-bottom: 4px;
}

.textContainer>h4 {
margin-bottom: 8px;
}

.textContainer>p:not(:last-child) {
margin-bottom: 8px;
}
Expand Down
11 changes: 7 additions & 4 deletions frontend/components/detailSections/DetailSection_Senator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { deserializeToInstances } from '@/functions/serialize'
import Collection from '@/classes/Collection'
import SenatorActionLog from '@/classes/SenatorActionLog'
import ActionLogContainer from "@/components/actionLogs/ActionLog"
import TermLink from '@/components/TermLink'

type FixedAttribute = {
name: "military" | "oratory" | "loyalty"
Expand Down Expand Up @@ -56,7 +57,7 @@ const SenatorDetails = (props: SenatorDetailsProps) => {
allFactions,
allSenators, setAllSenators,
allTitles,
selectedEntity,
selectedDetail,
actionLogs, setActionLogs,
senatorActionLogs, setSenatorActionLogs,
senatorDetailTab, setSenatorDetailTab
Expand All @@ -65,7 +66,7 @@ const SenatorDetails = (props: SenatorDetailsProps) => {
const scrollableAreaRef = useRef<HTMLDivElement | null>(null)

// Get senator-specific data
const senator: Senator | null = selectedEntity?.id ? allSenators.byId[selectedEntity.id] ?? null : null
const senator: Senator | null = selectedDetail?.id ? allSenators.byId[selectedDetail.id] ?? null : null
const faction: Faction | null = senator?.faction ? allFactions.byId[senator.faction] ?? null : null
const player: Player | null = faction?.player ? allPlayers.byId[faction.player] ?? null : null
const majorOffice: Title | null = senator ? allTitles.asArray.find(t => t.senator === senator.id && t.major_office == true) ?? null : null
Expand Down Expand Up @@ -226,7 +227,7 @@ const SenatorDetails = (props: SenatorDetailsProps) => {
<div className={styles.primaryArea}>
<div className={styles.portraitContainer}><SenatorPortrait senator={senator} size={getPortraitSize()} /></div>
<div className={styles.textContainer}>
<p><b>{senator.displayName}</b></p>
<h4><b>{senator.displayName}</b></h4>
<p>
{faction ?
<span>
Expand All @@ -238,7 +239,9 @@ const SenatorDetails = (props: SenatorDetailsProps) => {
(senator.alive ? 'Unaligned' : 'Dead')
}
</p>
{majorOffice && <p>Serving as <b>{majorOffice?.name}</b></p>}
{majorOffice &&
<p>Serving as <TermLink name={majorOffice.name == "Temporary Rome Consul" ? "Rome Consul" : majorOffice.name} displayName={majorOffice.name} includeIcon /></p>
}
</div>
</div>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
Expand Down
Loading

0 comments on commit 23ccbef

Please sign in to comment.