mancala/apps/frontend/src/components/home/HomeSection.tsx
Halit Aksoy a65662f695 feat(frontend): show ongoing, live, popular and recent games on the home page
- Banner for the user's game in progress with a Continue button
- Live games as cards with the real board, updated over WebSocket; the
  most watched finished games when nothing is live
- The user's last 3 games, from their side of the board, with the result
  as they would say it
- The lobby offers to continue the game in progress when a new one is
  refused
- Spectators register once connected and identified, and again after a
  reconnect, so they are counted
- The backend includes games that ended but are not saved yet in /game/:id
  and the lists
2026-10-16 00:27:06 +03:00

46 lines
1.6 KiB
TypeScript

import * as React from "react";
import { FunctionComponent } from "react";
import { getColorByBrightness } from "@mancala/core";
import { Context } from "../../context/context";
// A titled block of the home page; children are laid out as wrapping cards.
const HomeSection: FunctionComponent<{ context: Context, title: string, emptyText?: string }> = (props) => {
const theme = props.context.themeManager.theme;
const textColor = getColorByBrightness(theme.background, theme.textColor, theme.textLightColor);
const isEmpty = React.Children.count(props.children) === 0;
return (
<section style={{ color: textColor }}>
<h3>{props.title}</h3>
{isEmpty && props.emptyText ? <p className="empty">{props.emptyText}</p> : <div className="cards">{props.children}</div>}
<style jsx>{`
section {
width: 100%;
max-width: 900px;
padding: 0 16px;
box-sizing: border-box;
}
h3 {
margin: 24px 0 12px;
}
.cards {
display: flex;
flex-wrap: wrap;
gap: 16px;
justify-content: flex-start;
}
.empty {
opacity: 0.7;
margin: 0;
}
@media (max-width: 600px) {
.cards {
justify-content: center;
}
}
`}</style>
</section>
);
};
export default HomeSection;