Skip to content

Commit

Permalink
UI improvements (#377)
Browse files Browse the repository at this point in the history
* Change code order

Change the code order to match the order of items as they appear in the UI from left to right.

* Add "Your faction has X secrets" text

* Remove "Secret" from secret items

Remove the word "Secret" from individual secrets shown in the secrets list, since it's already obvious that the item is a secret.

* Improve the faction part of the meta section

Change the "Playing as the X Faction" part of the meta section to look better and add two faction attributes here: votes and secrets.

Create a new component `AttributeFlex`, which is similar to `AttributeGrid` except it's a flex rather than a grid. This introduces no new stuff, but is an extraction of some code that was already in `FactionListItem`. The purpose of the extraction is for use in the `MetaSection` in addition to the existing use in `FactionListItem`.

* Add conditional "Your" to faction description

Make the faction details description start out with "Your Faction..." if the selected faction is controlled by the user.
  • Loading branch information
iamlogand authored Jan 17, 2024
1 parent 167c5df commit 54a2c64
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 58 deletions.
45 changes: 45 additions & 0 deletions frontend/components/AttributeFlex.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Image from "next/image"
import { Tooltip } from "@mui/material"
import { capitalize } from "@mui/material/utils"

export interface Attribute {
name: string
value: number
icon: string
}

interface AttributeGridProps {
attributes: Attribute[]
}

const AttributeFlex = ({ attributes }: AttributeGridProps) => {
// Get attribute items
const getAttributeItem = (item: Attribute, index: number) => {
const titleCaseName = capitalize(item.name)
return (
<Tooltip key={index} title={titleCaseName} enterDelay={500} arrow>
<div className="w-[64px] grid grid-cols-[30px_30px] items-center justify-center bg-white shadow-[0px_0px_2px_2px_white] rounded">
<Image
src={item.icon}
height={28}
width={28}
alt={`${titleCaseName} icon`}
/>
<div className="w-8 text-center text-md font-semibold">
{item.value.toString()}
</div>
</div>
</Tooltip>
)
}

return (
<div className="p-[2px] flex flex-wrap gap-3 select-none">
{attributes.map((attribute: Attribute, index) =>
getAttributeItem(attribute, index)
)}
</div>
)
}

export default AttributeFlex
28 changes: 4 additions & 24 deletions frontend/components/FactionListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Image from "next/image"
import Tooltip from "@mui/material/Tooltip"
import { capitalize } from "@mui/material"

import SenatorPortrait from "@/components/SenatorPortrait"
import Collection from "@/classes/Collection"
Expand All @@ -11,7 +12,7 @@ import InfluenceIcon from "@/images/icons/influence.svg"
import TalentsIcon from "@/images/icons/talents.svg"
import VotesIcon from "@/images/icons/votes.svg"
import SecretsIcon from "@/images/icons/secrets.svg"
import { Attribute } from "@/components/AttributeGrid"
import AttributeFlex, { Attribute } from "@/components/AttributeFlex"

interface FactionListItemProps {
faction: Faction
Expand Down Expand Up @@ -53,28 +54,9 @@ const FactionListItem = (props: FactionListItemProps) => {
},
{ name: "talents", value: totalTalents, icon: TalentsIcon },
{ name: "votes", value: totalVotes, icon: VotesIcon },
{ name: "Secrets", value: secrets.length, icon: SecretsIcon },
{ name: "secrets", value: secrets.length, icon: SecretsIcon },
]

// Get attribute items
const getAttributeItem = (item: Attribute) => {
const titleCaseName =
item.name[0].toUpperCase() + item.name.slice(1)
return (
<Tooltip key={item.name} title={titleCaseName} enterDelay={500} arrow>
<div className="w-[64px] grid grid-cols-[30px_30px] items-center justify-center bg-white shadow-[0px_0px_2px_2px_white] rounded">
<Image
src={item.icon}
height={28}
width={28}
alt={`${titleCaseName} icon`}
/>
<div className="w-8 text-center text-md font-semibold">{item.value.toString()}</div>
</div>
</Tooltip>
)
}

if (!player?.user || senators.allIds.length === 0) return null

return (
Expand All @@ -91,9 +73,7 @@ const FactionListItem = (props: FactionListItemProps) => {
</b>{" "}
of {player.user.username}
</p>
<div className="p-[2px] flex flex-wrap gap-3 select-none">
{attributeItems.map((item) => getAttributeItem(item))}
</div>
<AttributeFlex attributes={attributeItems} />
<div className="flex flex-wrap gap-2">
{senators.asArray.map((senator: Senator) => (
<SenatorPortrait
Expand Down
98 changes: 66 additions & 32 deletions frontend/components/MetaSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import SenatorLink from "@/components/SenatorLink"
import TermLink from "@/components/TermLink"
import DeveloperTools from "@/components/DeveloperTools"
import TimeIcon from "@/images/icons/time.svg"
import VotesIcon from "@/images/icons/votes.svg"
import SecretsIcon from "@/images/icons/secrets.svg"
import AttributeFlex, { Attribute } from "@/components/AttributeFlex"
import Collection from "@/classes/Collection"

// Section showing meta info about the game
const MetaSection = () => {
Expand All @@ -28,6 +32,7 @@ const MetaSection = () => {
allPlayers,
allFactions,
allSenators,
allSecrets,
} = useGameContext()

// Get data
Expand All @@ -43,15 +48,72 @@ const MetaSection = () => {
? allFactions.asArray.find((f) => f.id == hrao.faction) ?? null
: null

let attributeItems: Attribute[] = []
if (faction) {
const senators = new Collection<Senator>(
allSenators.asArray
.filter((s) => s.alive) // Filter by alive
.filter((s) => s.faction === faction.id) // Filter by faction
.sort((a, b) => a.generation - b.generation) // Sort by generation
.sort((a, b) => a.name.localeCompare(b.name)) ?? [] // Sort by name
)
const totalVotes = senators.asArray.reduce(
(total, senator) => total + senator.votes,
0
)
const secrets = allSecrets.asArray.filter((s) => s.faction === faction.id)
attributeItems = [
{ name: "votes", value: totalVotes, icon: VotesIcon },
{ name: "secrets", value: secrets.length, icon: SecretsIcon },
]
}

if (game && latestStep && latestTurn && latestPhase) {
return (
<section className="flex flex-col lg:flex-row-reverse gap-2 align-center justify-between rounded bg-stone-200">
<div className="self-stretch py-3 px-6 flex gap-6 justify-between bg-stone-50 rounded shadow">
<div className="flex flex-col gap-2">
<section className="flex flex-col-reverse lg:flex-row gap-2 align-center justify-between rounded bg-stone-200">
<div className="flex-1 flex flex-col lg:flex-row gap-3 items-center justify-start">
{faction && (
<div
className="flex flex-col justify-around self-stretch px-4 py-2 rounded shadow"
style={{
backgroundColor: faction.getColor(100),
}}
>
<h3 className="text-sm">Your Faction</h3>
<div className="flex items-center gap-3">
<div>
<FactionLink faction={faction} includeIcon />
</div>
<AttributeFlex attributes={attributeItems} />
</div>
</div>
)}
{hrao && (
<div className="p-3 border border-solid border-stone-300 rounded shadow-inner bg-stone-100">
<span>
The{" "}
<TermLink
name="HRAO"
tooltipTitle="Highest Ranking Available Official"
/>{" "}
is <SenatorLink senator={hrao} />
{hraoFaction && (
<span>
{" "}
of <FactionLink faction={hraoFaction} includeIcon />
</span>
)}
</span>
</div>
)}
<DeveloperTools />
</div>
<div className="self-stretch py-3 px-4 flex gap-6 justify-between bg-stone-50 rounded shadow">
<div className="flex flex-col gap-2 justify-around">
<h2 className="leading-tight m-0 text-lg">{game.name}</h2>
<span
title={`Step ${latestStep?.index.toString()}`}
style={{ fontSize: 14 }}
className="text-sm"
>
<Image
src={TimeIcon}
Expand All @@ -78,34 +140,6 @@ const MetaSection = () => {
</Button>
</div>
</div>
<div className="flex-1 p-3 flex flex-col lg:flex-row gap-3 items-center justify-start">
<DeveloperTools />
{faction && (
<div className="p-3 border border-solid border-stone-300 rounded shadow-inner bg-stone-100">
<span>
Playing as the <FactionLink faction={faction} includeIcon />
</span>
</div>
)}
{hrao && (
<div className="p-3 border border-solid border-stone-300 rounded shadow-inner bg-stone-100">
<span>
The{" "}
<TermLink
name="HRAO"
tooltipTitle="Highest Ranking Available Official"
/>{" "}
is <SenatorLink senator={hrao} />
{hraoFaction && (
<span>
{" "}
of <FactionLink faction={hraoFaction} includeIcon />
</span>
)}
</span>
</div>
)}
</div>
</section>
)
} else {
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/SecretList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const SecretList = ({ faction }: { faction: Faction }) => {
className="list-none border border-solid border-red-600 rounded p-4 px-5 bg-stone-50 shadow-[inset_0_0_10px_0px_hsla(0,72%,51%,0.5)]"
>
<div className="flex flex-wrap justify-between gap-x-4 gap-y-2 text-sm">
<div>{capitalize(secret.type as string)} Secret</div>
<div>{capitalize(secret.type as string)}</div>
<div className="flex justify-end items-center gap-1 text-red-600">
<VisibilityOffIcon fontSize="small" /> <i>Hidden from others</i>
</div>
Expand Down
11 changes: 10 additions & 1 deletion frontend/components/detailSections/DetailSection_Faction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ const FactionDetails = () => {
const significantSenatorCount = hraoSenator ? 1 : 0 + majorOffices.length
return (
<p>
The {faction.getName()} Faction
{currentFaction && currentFaction?.id === faction.id ? (
"Your"
) : (
<span>The {faction.getName()}</span>
)}{" "}
Faction
{factionLeader && (
<span>
, led by <SenatorLink senator={factionLeader} />,
Expand Down Expand Up @@ -235,6 +240,10 @@ const FactionDetails = () => {
currentFaction &&
currentFaction.id === faction.id && (
<div className="h-full p-4 box-border">
<div className="mb-3">
Your faction has {secrets.length} secret
{secrets.length != 1 && "s"}:
</div>
<SecretList faction={faction} />
</div>
)}
Expand Down

0 comments on commit 54a2c64

Please sign in to comment.