diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 88e18595..be6bc2ae 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -121,20 +121,21 @@ def destroy end end - SHIPPING_PAUSE_START = Time.parse("2026-05-10 22:00:00 UTC").freeze - SHIPPING_RESUME = Time.parse("2026-05-11 22:00:00 UTC").freeze - REJECTION_EXCEPTION_START = (SHIPPING_PAUSE_START - 2.days).freeze + # Shipping locked for good when the game ended on July 6th, 2026. Projects + # rejected after the lock may still be re-shipped, so their authors can + # address the rejection. + SHIPPING_LOCKED_AT = Time.parse("2026-07-06 00:00:00 UTC").freeze def ship authorize @project - if Time.current >= SHIPPING_PAUSE_START && Time.current < SHIPPING_RESUME - unless recently_rejected_reship? || current_user.admin? + if Time.current >= SHIPPING_LOCKED_AT + unless rejected_after_lock? || current_user.admin? track_event("project_ship_failed", { project_id: @project.id, - reason: "shipping_paused" + reason: "shipping_locked" }) - redirect_to manage_project_path(@project), flash: { alert: "Shipping is temporarily paused as reviewers work to review projects of people who are qualifying for the HCTG event. It will be unpaused at 6:00pm ET on May 11th, 2026." } + redirect_to manage_project_path(@project), flash: { alert: "Shipping is locked now that the game has ended. Projects rejected after shipping locked can still be re-shipped." } return end end @@ -216,11 +217,10 @@ def allow_reship private - def recently_rejected_reship? + def rejected_after_lock? @project.aasm_state == "rejected" && @project.rejected_at.present? && - @project.rejected_at >= REJECTION_EXCEPTION_START && - @project.rejected_at < SHIPPING_PAUSE_START + @project.rejected_at >= SHIPPING_LOCKED_AT end def project_params diff --git a/app/frontend/components/projects/ProjectForm.tsx b/app/frontend/components/projects/ProjectForm.tsx index 76ffab47..7a788cee 100644 --- a/app/frontend/components/projects/ProjectForm.tsx +++ b/app/frontend/components/projects/ProjectForm.tsx @@ -5,10 +5,10 @@ import type { ProjectTag } from "@/interfaces/project_tag"; import type { SharedProps } from "@/types"; import formatTime from "@/utils/formatTime"; import { - isShippingPaused, - isShippingPausedForProject, - SHIPPING_PAUSE_MESSAGE, -} from "@/utils/shippingPause"; + isShippingLocked, + isShippingLockedForProject, + SHIPPING_LOCK_MESSAGE, +} from "@/utils/shippingLock"; import { useMemo, useState, useEffect, useRef, useCallback } from "react"; import arrowIcon from "@/assets/icons/arrow.svg"; import clsx from "clsx"; @@ -274,13 +274,13 @@ export default function ProjectForm({ const disabled = project?.aasm_state === "submitted"; const idvVerified = props.user.verification_status === "verified"; const isAdmin = props.user.is_admin; - const shippingPaused = isAdmin + const shippingLocked = isAdmin ? false : project - ? isShippingPausedForProject(project) - : isShippingPaused(); + ? isShippingLockedForProject(project) + : isShippingLocked(); const hasRejectionException = - !isAdmin && isShippingPaused() && !shippingPaused; + !isAdmin && isShippingLocked() && !shippingLocked; const rejectedAwaitingReship = project?.needs_reship_allowance ?? false; const shipsGloballyDisabled = !props.user.ships_enabled && @@ -670,20 +670,20 @@ export default function ProjectForm({ - {shippingPaused && + {shippingLocked && project.reported_seconds > project.approved_seconds && (
- {SHIPPING_PAUSE_MESSAGE} + {SHIPPING_LOCK_MESSAGE}
)} {hasRejectionException && project.reported_seconds > project.approved_seconds && (- Shipping is temporarily paused, but you can re-ship this - project because it was rejected in the two days before the - pause began. Note: if your project is rejected again while - shipping is paused, you will not be able to re-ship it - until the pause ends at 5:00pm ET on May 11th, 2026. + Shipping is locked now that the game has ended, but you + can re-ship this project because it was rejected after + shipping locked.
)} - {!shippingPaused && + {!shippingLocked && rejectedAwaitingReship && project.reported_seconds > project.approved_seconds && (- This project was rejected. A reviewer needs to allow it - to be reshipped before you can resubmit it. + This project was rejected. A reviewer needs to allow it to + be reshipped before you can resubmit it.
)} - {!shippingPaused && + {!shippingLocked && !rejectedAwaitingReship && shipsGloballyDisabled && project.reported_seconds > project.approved_seconds && ( diff --git a/app/frontend/pages/projects/index.tsx b/app/frontend/pages/projects/index.tsx index 0155dee7..2131b94e 100644 --- a/app/frontend/pages/projects/index.tsx +++ b/app/frontend/pages/projects/index.tsx @@ -3,10 +3,10 @@ import IdvVerificationAlert from "@/components/IdvVerificationAlert"; import PageHeading from "@/components/layout/PageHeading"; import ProjectList from "@/components/projects/ProjectList"; import { - isShippingPaused, - isShippingPausedForProject, - SHIPPING_PAUSE_MESSAGE, -} from "@/utils/shippingPause"; + isShippingLocked, + isShippingLockedForProject, + SHIPPING_LOCK_MESSAGE, +} from "@/utils/shippingLock"; import { usePage } from "@inertiajs/react"; import type { SharedProps } from "@/types"; @@ -15,10 +15,10 @@ import type { Project } from "@/interfaces/project"; export default function Index({ projects }: { projects: Project[] }) { const { props } = usePage{SHIPPING_PAUSE_MESSAGE}
+ Shipping locked +{SHIPPING_LOCK_MESSAGE}