Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1802,6 +1802,6 @@ For questions, issues, or contributions:

---

**Last Updated**: November 24, 2025
**Version**: 2.3.2 - Username Validation & Lobby Refactor
**Last Updated**: November 26, 2025
**Version**: 2.3.3 - Components Architecture Refactor
**Status**: ✅ Production Ready (API + Web + Docker + Timer Sync + Calibration)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

**League of Legends Website Tool: Easily Time and Communicate Summoner Spells - THE FLASH! 🌟**

[![Version](https://img.shields.io/badge/version-2.3.2-brightgreen?style=flat)](https://github.com/yourusername/LolTimeFlash/releases)
[![Version](https://img.shields.io/badge/version-2.3.3-brightgreen?style=flat)](https://github.com/yourusername/LolTimeFlash/releases)
[![Next.js](https://img.shields.io/badge/Next.js-16.0.1-black?style=flat&logo=next.js)](https://nextjs.org/)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.7.2-blue?style=flat&logo=typescript)](https://www.typescriptlang.org/)
[![Socket.IO](https://img.shields.io/badge/Socket.IO-4.8.1-010101?style=flat&logo=socket.io)](https://socket.io/)
Expand Down
40 changes: 40 additions & 0 deletions VERSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,46 @@

## 📚 Version History

### Version 2.3.3 - November 2025 (Components Architecture Refactor)

**Refactoring** :

- ♻️ **Components Organization** : Réorganisation des composants en dossiers logiques (`game/`, `room/`, `status/`, `controls/`)
- 🔄 **Path Aliases Migration** : Migration de tous les imports relatifs vers des alias TypeScript (`@/features/game/...`)
- 📁 **Simplified Structure** : Suppression des dossiers `ui/` et `input/` inutiles

**Technical Changes** :

**Frontend** :
- Nouvelle structure : `components/game/`, `components/room/`, `components/status/`, `components/controls/`
- Migration complète des imports relatifs vers `@/features/game/...`
- Création de barrel exports (`index.ts`) pour chaque dossier
- Amélioration du support IDE (autocomplete, refactoring)

**Fichiers Modifiés** :

| Fichier | Changements |
| ------------------------------------------------------------ | ---------------------------------------------- |
| `apps/web/features/game/components/game/*` | Déplacés depuis root, imports mis à jour |
| `apps/web/features/game/components/room/*` | Déplacés depuis root, imports mis à jour |
| `apps/web/features/game/components/status/*` | Déplacés depuis root, imports mis à jour |
| `apps/web/features/game/components/controls/*` | Déplacés depuis root, imports mis à jour |
| `apps/web/features/game/components/*.tsx` | Imports mis à jour vers alias |
| `apps/web/features/game/screens/*.tsx` | Imports mis à jour vers alias |
| `apps/web/features/game/contexts/*.tsx` | Imports mis à jour vers alias |
| `apps/web/features/game/hooks/*.ts` | Imports mis à jour vers alias |
| `apps/web/features/game/constants/*.ts` | Imports mis à jour vers alias |

**Impact** :

- ✅ Organisation améliorée (composants groupés par fonctionnalité)
- ✅ Imports cohérents (tous utilisent des alias)
- ✅ Support IDE amélioré (autocomplete, refactoring)
- ✅ Maintenabilité accrue (navigation facilitée)
- ✅ Scalabilité améliorée (ajout de composants simplifié)

---

### Version 2.3.2 - November 2025 (Username Validation & Lobby Refactor)

**New Features** :
Expand Down
118 changes: 118 additions & 0 deletions apps/web/components/ui/drawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
"use client"

import * as React from "react"
import { Drawer as DrawerPrimitive } from "vaul"

import { cn } from "@/lib/utils"

const Drawer = ({
shouldScaleBackground = true,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
<DrawerPrimitive.Root
shouldScaleBackground={shouldScaleBackground}
{...props}
/>
)
Drawer.displayName = "Drawer"

const DrawerTrigger = DrawerPrimitive.Trigger

const DrawerPortal = DrawerPrimitive.Portal

const DrawerClose = DrawerPrimitive.Close

const DrawerOverlay = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Overlay
ref={ref}
className={cn("fixed inset-0 z-50 bg-black/80", className)}
{...props}
/>
))
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName

const DrawerContent = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DrawerPortal>
<DrawerOverlay />
<DrawerPrimitive.Content
ref={ref}
className={cn(
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
className
)}
{...props}
>
<div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
))
DrawerContent.displayName = "DrawerContent"

const DrawerHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
{...props}
/>
)
DrawerHeader.displayName = "DrawerHeader"

const DrawerFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
{...props}
/>
)
DrawerFooter.displayName = "DrawerFooter"

const DrawerTitle = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Title
ref={ref}
className={cn(
"text-lg font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
))
DrawerTitle.displayName = DrawerPrimitive.Title.displayName

const DrawerDescription = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
DrawerDescription.displayName = DrawerPrimitive.Description.displayName

export {
Drawer,
DrawerPortal,
DrawerOverlay,
DrawerTrigger,
DrawerClose,
DrawerContent,
DrawerHeader,
DrawerFooter,
DrawerTitle,
DrawerDescription,
}
161 changes: 161 additions & 0 deletions apps/web/components/ui/select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
"use client"

import * as React from "react"
import * as SelectPrimitive from "@radix-ui/react-select"
import { FaCheck } from "react-icons/fa"
import { HiChevronDown, HiChevronUp } from "react-icons/hi"

import { cn } from "@/lib/utils"

const Select = SelectPrimitive.Root

const SelectGroup = SelectPrimitive.Group

const SelectValue = SelectPrimitive.Value

const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
className
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<HiChevronDown className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
))
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName

const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<HiChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
))
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName

const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
{...props}
>
<HiChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
))
SelectScrollDownButton.displayName =
SelectPrimitive.ScrollDownButton.displayName

const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = "popper", ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className
)}
position={position}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
className={cn(
"p-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
)}
>
{children}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
))
SelectContent.displayName = SelectPrimitive.Content.displayName

const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label
ref={ref}
className={cn("px-2 py-1.5 text-sm font-semibold", className)}
{...props}
/>
))
SelectLabel.displayName = SelectPrimitive.Label.displayName

const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
{...props}
>
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<FaCheck className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
))
SelectItem.displayName = SelectPrimitive.Item.displayName

const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
))
SelectSeparator.displayName = SelectPrimitive.Separator.displayName

export {
Select,
SelectGroup,
SelectValue,
SelectTrigger,
SelectContent,
SelectLabel,
SelectItem,
SelectSeparator,
SelectScrollUpButton,
SelectScrollDownButton,
}

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const GameControlsComponent = (props: IGameControlsProps) => {
<>
{/* Back Button */}
<Button
className="absolute left-6 top-6 sm:left-20 sm:top-10"
className="absolute left-6 top-10 sm:left-20 sm:top-10"
onClick={handleGoBack}
variant="outline"
size="icon"
Expand All @@ -34,7 +34,7 @@ const GameControlsComponent = (props: IGameControlsProps) => {

{/* Volume Button */}
<Button
className="absolute right-6 top-6 sm:left-20 sm:top-24"
className="absolute hidden sm:left-20 sm:top-24 sm:flex"
onClick={onToggleVolume}
variant="outline"
size="icon"
Expand Down
2 changes: 2 additions & 0 deletions apps/web/features/game/components/controls/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { GameControls } from './game-controls.component'

Loading
Loading