This commit is contained in:
Kalle
2026-08-16 11:05:12 +03:00
parent c0fdb922fd
commit e3e071b6a5
30 changed files with 3023 additions and 136 deletions

View File

@@ -309,12 +309,13 @@ function MobilePanel({
<Modal
className={clsx(styles.panel, skipAnimation && styles.noAnimation)}
>
<Dialog className={styles.panelDialog}>
<Dialog data-testid="mobile-nav-panel" className={styles.panelDialog}>
<header className={styles.panelHeader}>
<div className={styles.panelIconContainer}>{icon}</div>
<h2 className={styles.panelTitle}>{title}</h2>
<button
type="button"
data-testid="panel-close-button"
className={styles.panelCloseButton}
onClick={onClose}
>
@@ -363,7 +364,7 @@ function MenuOverlay({
skipAnimation && styles.noAnimation,
)}
>
<Dialog className={styles.panelDialog}>
<Dialog data-testid="mobile-nav-panel" className={styles.panelDialog}>
<header className={styles.menuHeader}>
<div className={styles.panelIconContainer}>
<Menu size={18} />
@@ -387,6 +388,7 @@ function MenuOverlay({
/>
<button
type="button"
data-testid="panel-close-button"
className={styles.panelCloseButton}
onClick={onClose}
>
@@ -433,7 +435,7 @@ function MenuOverlay({
</h3>
</header>
{streams.length === 0 ? (
<div className={styles.sideNavEmpty}>
<div data-testid="side-nav-empty" className={styles.sideNavEmpty}>
{t("front:sideNav.noStreams")}
</div>
) : null}
@@ -483,7 +485,7 @@ function FriendsPanel({
<FriendMenu key={friend.id} {...friend} onNavigate={onClose} />
))
) : (
<div className={styles.sideNavEmpty}>
<div data-testid="side-nav-empty" className={styles.sideNavEmpty}>
{user
? t("front:sideNav.friends.noFriends")
: t("front:sideNav.friends.notLoggedIn")}
@@ -573,7 +575,12 @@ function YouPanel({
onClick={onClose}
>
<Avatar user={user} size="sm" />
<span className={styles.youPanelUsername}>{user.username}</span>
<span
data-testid="you-panel-username"
className={styles.youPanelUsername}
>
{user.username}
</span>
</Link>
<Link
to={SETTINGS_PAGE}
@@ -619,7 +626,7 @@ function ChatPanel({
skipAnimation && styles.noAnimation,
)}
>
<Dialog className={styles.panelDialog}>
<Dialog data-testid="mobile-nav-panel" className={styles.panelDialog}>
<ChatSidebar onClose={onClose} />
<GhostTabBar onTabPress={onTabPress} isLoggedIn={isLoggedIn} />
</Dialog>
@@ -652,6 +659,7 @@ function GhostTabBar({
<button
key={tab}
type="button"
data-testid="ghost-tab"
className={styles.ghostTab}
tabIndex={-1}
onClick={() => onTabPress(tab)}

View File

@@ -25,6 +25,7 @@ export function SideNav({
}) {
return (
<nav
data-testid="side-nav"
className={clsx(styles.sideNav, className, {
[styles.sideNavCollapsed]: collapsed,
})}
@@ -54,7 +55,7 @@ export function SideNavHeader({
action?: React.ReactNode;
}) {
return (
<header className={styles.sideNavHeader}>
<header data-testid="side-nav-header" className={styles.sideNavHeader}>
{icon ? <div className={styles.iconContainer}>{icon}</div> : null}
<h2>{children}</h2>
{action ? (
@@ -115,6 +116,7 @@ function ListItemContent({
<div className={styles.listLinkSubtitleRow}>
{subtitle ? (
<span
data-testid="list-item-subtitle"
className={styles.listLinkSubtitle}
suppressHydrationWarning={suppressSubtitleHydrationWarning}
>
@@ -123,6 +125,7 @@ function ListItemContent({
) : null}
{typeof badge === "string" ? (
<span
data-testid="list-item-badge"
className={clsx(styles.listLinkBadge, {
[styles.listLinkBadgeWarning]: badgeVariant === "warning",
})}
@@ -167,6 +170,7 @@ export function ListLink({
return (
<Link
to={to}
data-testid="list-link"
className={styles.listLink}
onClick={onClick}
aria-current={isActive ? "page" : undefined}
@@ -202,7 +206,7 @@ export function ListButton({
badgeVariant?: "default" | "warning";
}) {
return (
<Button className={styles.listButton}>
<Button data-testid="list-button" className={styles.listButton}>
<ListItemContent
user={user}
subtitle={subtitle}

View File

@@ -78,7 +78,10 @@ export function StreamListItems({
return (
<React.Fragment key={stream.id}>
{showUpcomingDivider ? (
<div className={styles.upcomingDivider}>
<div
data-testid="upcoming-divider"
className={styles.upcomingDivider}
>
{t("front:sideNav.streams.upcoming")}
</div>
) : null}
@@ -169,7 +172,12 @@ function SaveTournamentStreamButton({
/>
<input type="hidden" name="revalidateRoot" value="true" />
<button type="submit" className={styles.saveIconButton} title="Save">
<Icon size={14} />
<Icon
size={14}
data-testid={
optimisticSaved ? "stream-saved-icon" : "stream-save-icon"
}
/>
</button>
</fetcher.Form>
);

View File

@@ -106,7 +106,7 @@ function DevMenu() {
isOpen={isOpen}
onOpenChange={setIsOpen}
>
<div className={styles.menuContent}>
<div data-testid="menu-content" className={styles.menuContent}>
{DEV_IMPERSONATE_ITEMS.map((item) => (
<Form
key={item.name}
@@ -226,7 +226,7 @@ function CategoryMenu({
isOpen={isOpen}
onOpenChange={setIsOpen}
>
<div className={styles.menuContent}>
<div data-testid="menu-content" className={styles.menuContent}>
{visibleItems.map((item) => (
<Link
key={item.url}

View File

@@ -337,7 +337,9 @@ export function Layout({
</ListLink>
))
) : (
<div className={styles.sideNavEmpty}>{t("front:sideNav.noEvents")}</div>
<div data-testid="side-nav-empty" className={styles.sideNavEmpty}>
{t("front:sideNav.noEvents")}
</div>
)}
<SideNavHeader
@@ -371,7 +373,7 @@ export function Layout({
.slice(0, MAX_DESKTOP_FRIENDS)
.map((friend) => <FriendMenu key={friend.id} {...friend} />)
) : (
<div className={styles.sideNavEmpty}>
<div data-testid="side-nav-empty" className={styles.sideNavEmpty}>
{user
? t("front:sideNav.friends.noFriends")
: t("front:sideNav.friends.notLoggedIn")}
@@ -380,7 +382,7 @@ export function Layout({
<SideNavHeader icon={<Tv />}>{t("front:sideNav.streams")}</SideNavHeader>
{streams.length === 0 ? (
<div className={styles.sideNavEmpty}>
<div data-testid="side-nav-empty" className={styles.sideNavEmpty}>
{t("front:sideNav.noStreams")}
</div>
) : null}