Add boto3 dependency and update exercise/machine assets
- Added boto3 as a dependency in pyproject.toml and uv.lock. - Introduced multiple new exercise images in various formats (jpg, webp, avif, png). - Added new machine images to enhance the workout assets library.
This commit is contained in:
@@ -1,8 +1,17 @@
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
import type { CatalogEntity, CatalogKind, Workout } from "../../types";
|
||||
import type { ActivityCategory, CatalogEntity, CatalogKind, Workout } from "../../types";
|
||||
import { categoryLabels, measurementLabels } from "../catalog/meta";
|
||||
import { useCatalog } from "../catalog/hooks";
|
||||
|
||||
const categoryTabs: Array<ActivityCategory | "all" | "arms"> = ["all", "chest", "back", "legs", "shoulders", "arms", "core", "cardio"];
|
||||
|
||||
function categoryTabLabel(category: ActivityCategory | "all" | "arms") {
|
||||
if (category === "all") return "Все";
|
||||
if (category === "arms") return "Руки";
|
||||
return categoryLabels[category];
|
||||
}
|
||||
|
||||
export function AddExerciseDrawer({
|
||||
open,
|
||||
token,
|
||||
@@ -20,11 +29,13 @@ export function AddExerciseDrawer({
|
||||
}) {
|
||||
const [kind, setKind] = useState<CatalogKind>("exercise");
|
||||
const [search, setSearch] = useState("");
|
||||
const { exercises, equipment } = useCatalog(token);
|
||||
const [category, setCategory] = useState<ActivityCategory | "all" | "arms">("all");
|
||||
const { exercises, machines } = useCatalog(token);
|
||||
|
||||
const addedIds = useMemo(() => {
|
||||
const ids = new Set<string>();
|
||||
workout.items.forEach((item) => {
|
||||
if (item.activity_source_id) ids.add(item.activity_source_id);
|
||||
if (item.exercise_id) ids.add(item.exercise_id);
|
||||
if (item.equipment_id) ids.add(item.equipment_id);
|
||||
});
|
||||
@@ -32,10 +43,15 @@ export function AddExerciseDrawer({
|
||||
}, [workout.items]);
|
||||
|
||||
const list = useMemo(() => {
|
||||
const source = kind === "exercise" ? exercises.data ?? [] : equipment.data ?? [];
|
||||
const source = kind === "exercise" ? exercises.data ?? [] : machines.data ?? [];
|
||||
const needle = search.trim().toLowerCase();
|
||||
return needle ? source.filter((entity) => entity.name.toLowerCase().includes(needle)) : source;
|
||||
}, [kind, search, exercises.data, equipment.data]);
|
||||
return source.filter((entity) => {
|
||||
if (category === "arms" && entity.category !== "biceps" && entity.category !== "triceps") return false;
|
||||
if (category !== "all" && category !== "arms" && entity.category !== category) return false;
|
||||
if (!needle) return true;
|
||||
return `${entity.title} ${entity.description ?? ""}`.toLowerCase().includes(needle);
|
||||
});
|
||||
}, [category, kind, search, exercises.data, machines.data]);
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
@@ -53,7 +69,12 @@ export function AddExerciseDrawer({
|
||||
<input className="drawer-search" placeholder="Поиск упражнения или тренажера" value={search} onChange={(event) => setSearch(event.target.value)} />
|
||||
<div className="segmented drawer-tabs">
|
||||
<button className={kind === "exercise" ? "active" : ""} onClick={() => setKind("exercise")}>Упражнения</button>
|
||||
<button className={kind === "equipment" ? "active" : ""} onClick={() => setKind("equipment")}>Тренажеры</button>
|
||||
<button className={kind === "machine" ? "active" : ""} onClick={() => setKind("machine")}>Тренажеры</button>
|
||||
</div>
|
||||
<div className="chip-row drawer-categories">
|
||||
{categoryTabs.map((tab) => (
|
||||
<button key={tab} className={category === tab ? "active" : ""} onClick={() => setCategory(tab)}>{categoryTabLabel(tab)}</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="drawer-list">
|
||||
@@ -61,10 +82,10 @@ export function AddExerciseDrawer({
|
||||
const added = addedIds.has(entity.id);
|
||||
return (
|
||||
<article className={`drawer-pick ${added ? "already-added" : ""}`} key={`${kind}-${entity.id}`} onClick={() => onAdd(entity, kind, true)}>
|
||||
{entity.image_s3_url ? <img src={entity.image_s3_url} alt="" /> : <span className="drawer-placeholder">{kind === "exercise" ? "EX" : "EQ"}</span>}
|
||||
{entity.image_s3_url ? <img src={entity.image_s3_url} alt="" /> : <span className="drawer-placeholder">{kind === "exercise" ? "EX" : "MC"}</span>}
|
||||
<div>
|
||||
<h3>{entity.name}</h3>
|
||||
<p>{entity.description || "Без описания"}</p>
|
||||
<h3>{entity.title}</h3>
|
||||
<p>{categoryLabels[entity.category]} · {measurementLabels[entity.measurement_type]}</p>
|
||||
{added && <b>В тренировке</b>}
|
||||
</div>
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user