# Tier List

> Build a tier maker app where users upload images and drag them into ranked tiers (A through F) — practicing HTML5 Drag and Drop and file uploads in React.

- Difficulty: intermediate
- Tags: useState, useRef, customHook
- Estimated time: 60 minutes
- Tests: 13
- Requires subscription: yes

## Overview

Build a tier maker app where users upload images and drag them into ranked tiers (A through F) — practicing **HTML5 Drag and Drop** and **file uploads** in React.


## Requirements

- Render a **"Tier List"** title at the top of the page.
- Render **six tier rows** labeled A, B, C, D, E, F with the correct background colors:
  - A: `#ff7f80`, B: `#ffc07f`, C: `#ffdf80`, D: `#fdff7f`, E: `#bfff7f`, F: `#7fff7f`
- Include **two action buttons** in the footer:
  - **Add** — opens a file picker to upload images.
  - **Reset** — moves all images back to the selector area.
- Provide a **selector area** at the bottom where unassigned images appear.
- Start with an **empty selector** and **empty tier rows** (no images preloaded).
- **File upload**:
  - Selecting one or more images via the file picker adds them to the selector.
  - Dragging files from the desktop onto the selector area also adds them.
- **Drag and drop**:
  - Dragging an image from the selector and dropping it on a tier row moves it there.
  - Dragging an image between tier rows moves it from one tier to another.
  - Dragging an image from a tier row back to the selector returns it to the pool.
  - While dragging over a tier row, the drop zone should highlight.
- **Reset** moves all images from tier rows back into the selector area.


## Notes

- All the drag-and-drop logic lives in `useTier.ts` — the file already exports the `Tier`, `Item` types and `TIERS`, `TIER_COLORS` constants. Implement the hook there.
- Use the **HTML5 Drag and Drop API** (`dragStart`, `dragOver`, `drop`, `dragEnd`, `dragLeave`) to handle image movement between the selector and tier rows.
- Use `FileReader.readAsDataURL()` to convert uploaded files into displayable image sources.
- Watch out for drag-and-drop event propagation: use `e.relatedTarget` checks in `dragLeave` handlers to avoid flickering when dragging over child elements within the same drop zone.
- How can you tell the difference between an image being dragged from a tier and a file being dropped from the desktop?
- Native HTML elements are not draggable by default — make sure images can be dragged, and consider adding visual feedback.
- The selector area should visually indicate when files are being dragged over it from the desktop (e.g., dashed border or background change).
- Keep `data-testid` attributes on key elements, tests are using it.


## Tests

01. renders the tier list title
02. renders all six tier labels
03. renders add and reset buttons
04. renders the selector area
05. renders the tier container with six drop zones
06. starts with an empty selector and empty tier rows

07. applies correct background colors to each tier label

08. adds images to the selector when files are selected
09. adds multiple images when multiple files are selected

10. moves all items back to the selector

11. moves an item from selector to a tier row
12. moves an item from one tier to another
13. moves an item from a tier back to the selector


