initial index

This commit is contained in:
41666 2023-05-22 21:04:29 -04:00
parent 62cc828d6a
commit 88015a98cd
21 changed files with 343 additions and 56 deletions

View file

@ -0,0 +1,30 @@
import type { ComplexStyleRule } from "@vanilla-extract/css";
import { style } from "@vanilla-extract/css";
export const bar = style({
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "row",
overflow: "hidden",
borderRadius: "0.4rem",
border: "2px solid #2d2d2d",
});
const shared: ComplexStyleRule = {
textAlign: "center",
};
export const left = style({
...shared,
backgroundColor: "#991cba",
});
export const center = style({
...shared,
backgroundColor: "#1564cc",
borderBottom: "1px solid #2d2d2d",
});
export const right = style({
...shared,
backgroundColor: "#d30101",
});

View file

@ -0,0 +1,32 @@
import { useMemo } from "react";
import type { Population } from "~/utils/saerro";
import { totalPopulation } from "~/utils/saerro";
import * as styles from "./faction-bar.css";
export const FactionBar = ({
population: { vs, nc, tr },
}: {
population: Population;
}) => {
const { vsPercent, ncPercent, trPercent } = useMemo(() => {
const total = totalPopulation({ vs, nc, tr, total: 0 });
return {
vsPercent: Math.floor((vs / total) * 100) || 0,
ncPercent: Math.floor((nc / total) * 100) || 0,
trPercent: Math.floor((tr / total) * 100) || 0,
};
}, [vs, nc, tr]);
return (
<div className={styles.bar}>
<div className={styles.left} style={{ flexGrow: vs + 1 }}>
{vsPercent}%
</div>
<div className={styles.center} style={{ flexGrow: nc + 1 }}>
{ncPercent}%
</div>
<div className={styles.right} style={{ flexGrow: tr + 1 }}>
{trPercent}%
</div>
</div>
);
};

View file

@ -0,0 +1,8 @@
import { style } from "@vanilla-extract/css";
export const container = style({
display: "flex",
flexBasis: "100%",
flexWrap: "wrap",
justifyContent: "center",
});

View file

@ -0,0 +1,22 @@
import { useMemo } from "react";
import type { Health, World } from "~/utils/saerro";
import { IndexWorld } from "./index-world";
import * as styles from "./index-world-container.css";
export const WorldContainer = ({
worlds,
health,
}: {
worlds: World[];
health: Health;
}) => (
<div className={styles.container}>
{worlds.map((world) => (
<IndexWorld
key={world.id}
world={world}
health={health.worlds.find((w) => world.name.toLowerCase() === w.name)}
/>
))}
</div>
);

View file

@ -0,0 +1,70 @@
import { style } from "@vanilla-extract/css";
export const container = style({
background: "#333",
flexBasis: "30%",
margin: "0.5rem",
});
export const header = style({
display: "flex",
alignItems: "center",
color: "inherit",
textDecoration: "none",
transition: "background-color 0.2s ease-in-out",
backgroundColor: "#222",
":hover": {
backgroundColor: "#383838",
},
});
export const headerName = style({
padding: "0.5rem",
fontSize: "1.5rem",
});
export const headerDetailsLink = style({
fontVariant: "small-caps",
fontSize: "0.8rem",
color: "#aaa",
paddingRight: "0.5rem",
});
export const headerMarkers = style({
fontSize: "0.8rem",
flex: 1,
fontWeight: "bold",
color: "#aaa",
});
export const circle = style({
display: "inline-block",
width: "0.4rem",
height: "0.4rem",
borderRadius: "50%",
marginLeft: "0.2rem",
});
export const details = style({
padding: "0.5rem",
});
export const population = style({
display: "flex",
alignItems: "center",
justifyContent: "space-evenly",
});
export const popFaction = style({
display: "flex",
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
});
export const popImage = style({
height: "1.5rem",
marginRight: "0.5rem",
});
export const totalPop = style({
fontWeight: "bold",
fontSize: "1.2rem",
});

View file

@ -1,18 +1,61 @@
import { World } from "~/utils/saerro";
import { Link } from "@remix-run/react";
import { Health, totalPopulation, World } from "~/utils/saerro";
import { humanTimeAgo } from "~/utils/strings";
import { worlds } from "~/utils/worlds";
import * as styles from "./index-world.css";
import vsLogo from "~/images/vs-100.png";
import ncLogo from "~/images/nc-100.png";
import trLogo from "~/images/tr-100.png";
import { FactionBar } from "./faction-bar";
export type IndexWorldProps = {
world: World;
health?: Health["worlds"][number];
};
export const IndexWorld = ({ world }: IndexWorldProps) => {
export const IndexWorld = ({ world, health }: IndexWorldProps) => {
const { platform, location } = worlds[String(world.id || "default")];
const timeSinceLastEvent = humanTimeAgo(
new Date().getTime() - new Date(health?.lastEvent || 0).getTime()
);
return (
<div>
<h1>
{world.name} (total: {world.population.total})
</h1>
<p>VS: {world.population.vs}</p>
<p>NC: {world.population.nc}</p>
<p>TR: {world.population.tr}</p>
<div className={styles.container}>
<Link to={`/worlds/${world.id}`} className={styles.header}>
<div className={styles.headerName}>{world.name}</div>
<div className={styles.headerMarkers}>
[{location}] [{platform}]{" "}
<div
className={styles.circle}
style={{
backgroundColor: health?.status === "UP" ? "limegreen" : "red",
}}
title={`Status: ${health?.status} || Last event: ${timeSinceLastEvent}`}
></div>
</div>
<div className={styles.headerDetailsLink}>DETAILS </div>
</Link>
<div className={styles.details}>
<div className={styles.population}>
<div className={styles.totalPop}>
{totalPopulation(world.population)}
</div>
<div className={styles.popFaction}>
<img className={styles.popImage} src={vsLogo} alt="VS" />{" "}
{world.population.vs}
</div>
<div className={styles.popFaction}>
<img className={styles.popImage} src={ncLogo} alt="NC" />{" "}
{world.population.nc}
</div>
<div className={styles.popFaction}>
<img className={styles.popImage} src={trLogo} alt="TR" />{" "}
{world.population.tr}
</div>
</div>
<FactionBar population={world.population} />
</div>
</div>
);
};