5.13.0: Карточки проектов и желаний на экране недели
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m10s

This commit is contained in:
poignatov
2026-03-05 12:42:52 +03:00
parent 2b7b056562
commit 7fdcbb75da
5 changed files with 90 additions and 29 deletions

View File

@@ -1 +1 @@
5.12.0 5.13.0

View File

@@ -1,6 +1,6 @@
{ {
"name": "play-life-web", "name": "play-life-web",
"version": "5.12.0", "version": "5.13.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -175,19 +175,34 @@
cursor: not-allowed; cursor: not-allowed;
} }
/* Внешний контейнер для карточки проекта */ /* Внешний контейнер для карточки проекта — без общей тени и рамки */
.project-card-wrapper { .project-card-wrapper {
border: 1px solid #e0e4ed; background-color: transparent;
border-radius: 1.5rem;
transition: all 0.3s;
box-shadow: 0 1px 3px 0 rgb(99 102 241 / 0.08);
background-color: #eef0f7;
} }
.project-card-wrapper:hover { /* Карточка с инфой по проекту — своя тень */
.project-card-inner {
box-shadow: 0 1px 3px 0 rgb(99 102 241 / 0.08);
transition: box-shadow 0.3s;
}
.project-card-inner:hover {
box-shadow: 0 2px 6px 0 rgb(99 102 241 / 0.12); box-shadow: 0 2px 6px 0 rgb(99 102 241 / 0.12);
} }
/* Блок с инфой по проекту: при наличии желаний убираем нижние закругления и добавляем отступ снизу */
.project-card-inner-with-wishes {
border-radius: 1.5rem 1.5rem 0 0 !important;
margin-bottom: 0.5rem;
}
/* Блок списка желаний: отдельная карточка со своей тенью */
.project-wishes-block {
background-color: #fff;
border-radius: 0 0 1.5rem 1.5rem;
box-shadow: 0 1px 3px 0 rgb(99 102 241 / 0.08);
}
/* Стили для горизонтального скролла желаний в карточке проекта */ /* Стили для горизонтального скролла желаний в карточке проекта */
.project-wishes-scroll { .project-wishes-scroll {
display: flex; display: flex;
@@ -226,6 +241,7 @@
border-radius: 8px; border-radius: 8px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
container-type: inline-size;
} }
.mini-wish-image img { .mini-wish-image img {
@@ -236,14 +252,37 @@
.mini-wish-overlay { .mini-wish-overlay {
position: absolute; position: absolute;
top: 0; inset: 0;
left: 0; z-index: 1;
right: 0; background: rgba(255, 255, 255, 0.65);
bottom: 0;
background: rgba(255, 255, 255, 0.4);
pointer-events: none; pointer-events: none;
} }
/* Текст баллов поверх пелены (отдельный слой, выше по z-index) */
.mini-wish-unlock-points {
position: absolute;
top: 0;
left: 4px;
right: 4px;
bottom: 0;
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
width: calc(100% - 8px);
max-width: calc(100% - 8px);
color: #5b6b8a;
/* font-size задаётся в JS по количеству цифр (auto-size) */
font-weight: 700;
line-height: 1.2;
pointer-events: none;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
box-sizing: border-box;
text-align: center;
}
.mini-wish-placeholder { .mini-wish-placeholder {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@@ -104,6 +104,17 @@ function MiniWishCard({ wish, onClick }) {
} }
} }
const cond = wish.first_locked_condition
const isPointsCondition = cond?.type === 'project_points'
const required = cond?.required_points ?? 0
const current = cond?.current_points ?? 0
const remaining = isPointsCondition ? Math.max(0, required - current) : 0
const showUnlockPoints = remaining > 0
// Auto-size: уменьшаем шрифт при большом количестве цифр, чтобы текст влезал
const digits = String(Math.round(remaining)).length
const fontSizePx = digits <= 1 ? 22 : digits === 2 ? 19 : digits === 3 ? 16 : 14
return ( return (
<div className="mini-wish-card" onClick={handleClick}> <div className="mini-wish-card" onClick={handleClick}>
<div className="mini-wish-image"> <div className="mini-wish-image">
@@ -112,7 +123,16 @@ function MiniWishCard({ wish, onClick }) {
) : ( ) : (
<div className="mini-wish-placeholder">🎁</div> <div className="mini-wish-placeholder">🎁</div>
)} )}
<div className="mini-wish-overlay"></div> <div className="mini-wish-overlay" aria-hidden="true" />
{showUnlockPoints && (
<div
className="mini-wish-unlock-points"
style={{ fontSize: `${fontSizePx}px` }}
aria-hidden="true"
>
{Math.round(remaining)}
</div>
)}
</div> </div>
</div> </div>
) )
@@ -206,7 +226,7 @@ function ProjectCard({ project, projectColor, onProjectClick, wishes = [], onWis
<div className="project-card-wrapper"> <div className="project-card-wrapper">
<div <div
onClick={handleClick} onClick={handleClick}
className="bg-white rounded-3xl py-3 px-4 transition-all duration-300 cursor-pointer" className={`project-card-inner bg-white py-3 px-4 transition-all duration-300 cursor-pointer ${hasWishes ? 'rounded-t-3xl project-card-inner-with-wishes' : 'rounded-3xl'}`}
> >
{/* Верхняя часть с названием и прогрессом */} {/* Верхняя часть с названием и прогрессом */}
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@@ -245,16 +265,18 @@ function ProjectCard({ project, projectColor, onProjectClick, wishes = [], onWis
</div> </div>
</div> </div>
{/* Горизонтальный список желаний */} {/* Горизонтальный список желаний в отдельном белом блоке */}
{hasWishes && ( {hasWishes && (
<div className="project-wishes-scroll"> <div className="project-wishes-block">
{wishes.map((wish) => ( <div className="project-wishes-scroll">
<MiniWishCard {wishes.map((wish) => (
key={wish.id} <MiniWishCard
wish={wish} key={wish.id}
onClick={onWishClick} wish={wish}
/> onClick={onWishClick}
))} />
))}
</div>
</div> </div>
)} )}
</div> </div>

View File

@@ -178,7 +178,7 @@
.progression-input { .progression-input {
width: 100%; width: 100%;
padding: 0.75rem; padding: 0.75rem;
padding-right: 4.5rem; padding-right: 4.75rem;
border: 1px solid #d1d5db; border: 1px solid #d1d5db;
border-radius: 0.375rem; border-radius: 0.375rem;
font-size: 1rem; font-size: 1rem;
@@ -212,11 +212,11 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 1.75rem; width: 2rem;
height: 1.75rem; height: 2rem;
border: none; border: none;
background: transparent; background: transparent;
font-size: 1rem; font-size: 1.125rem;
font-weight: 500; font-weight: 500;
color: #6b7280; color: #6b7280;
cursor: pointer; cursor: pointer;