This commit is contained in:
2026-01-10 08:48:01 +07:00
parent b6eecc4483
commit 2b6f2888ee
3 changed files with 53 additions and 3 deletions

View File

@@ -0,0 +1,30 @@
"""Add tracked_time_minutes to assignments
Revision ID: 029_add_tracked_time
Revises: 028_add_promo_codes
Create Date: 2026-01-10
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '029_add_tracked_time'
down_revision: Union[str, None] = '028_add_promo_codes'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# Add tracked_time_minutes column to assignments table
op.add_column(
'assignments',
sa.Column('tracked_time_minutes', sa.Integer(), nullable=False, server_default='0')
)
def downgrade() -> None:
op.drop_column('assignments', 'tracked_time_minutes')

View File

@@ -1418,9 +1418,28 @@ export function PlayPage() {
</div> </div>
<div className="flex items-center gap-3 mb-6 flex-wrap"> <div className="flex items-center gap-3 mb-6 flex-wrap">
<span className="px-3 py-1.5 bg-green-500/20 text-green-400 rounded-lg text-sm font-medium border border-green-500/30"> {/* Points - calculated from tracked time if available */}
+{currentAssignment.playthrough_info?.points} очков {currentAssignment.tracked_time_minutes !== undefined && currentAssignment.tracked_time_minutes > 0 ? (
</span> <span className="px-3 py-1.5 bg-green-500/20 text-green-400 rounded-lg text-sm font-medium border border-green-500/30">
~{Math.floor(currentAssignment.tracked_time_minutes / 60 * 30)} очков
</span>
) : (
<span className="px-3 py-1.5 bg-green-500/20 text-green-400 rounded-lg text-sm font-medium border border-green-500/30">
+{currentAssignment.playthrough_info?.points} очков
</span>
)}
{/* Time tracker indicator */}
{currentAssignment.tracked_time_minutes !== undefined && currentAssignment.tracked_time_minutes > 0 ? (
<span className="px-3 py-1.5 bg-neon-500/20 text-neon-400 rounded-lg text-sm font-medium border border-neon-500/30 flex items-center gap-1.5">
<Clock className="w-4 h-4" />
{Math.floor(currentAssignment.tracked_time_minutes / 60)}ч {currentAssignment.tracked_time_minutes % 60}м
</span>
) : (
<span className="px-3 py-1.5 bg-gray-500/20 text-gray-400 rounded-lg text-sm font-medium border border-gray-500/30 flex items-center gap-1.5">
<Clock className="w-4 h-4" />
Установите трекер
</span>
)}
</div> </div>
{currentAssignment.playthrough_info?.proof_hint && ( {currentAssignment.playthrough_info?.proof_hint && (

View File

@@ -270,6 +270,7 @@ export interface Assignment {
proof_comment: string | null proof_comment: string | null
points_earned: number points_earned: number
streak_at_completion: number | null streak_at_completion: number | null
tracked_time_minutes?: number // Time tracked by desktop app (for playthroughs)
started_at: string started_at: string
completed_at: string | null completed_at: string | null
drop_penalty: number drop_penalty: number