Skip to content

Commit 0a7613a

Browse files
committed
feat: sections remain locked until prev is finished
1 parent f41c5cb commit 0a7613a

2 files changed

Lines changed: 64 additions & 32 deletions

File tree

components/forms/pbctfForm.tsx

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,22 @@ const PBCTFForm: React.FC = () => {
102102
const agreeRules = watch("agreeRules");
103103
const consentLeaderboard = watch("consentLeaderboard");
104104
const allowContact = watch("allowContact");
105+
const stepSequence = participationType === "duo"
106+
? [0, 1, 2, 3, 4]
107+
: [0, 1, 3, 4];
108+
109+
const canAccessStep = (stepNumber: number) => {
110+
const stepIndex = stepSequence.indexOf(stepNumber);
111+
if (stepIndex === -1) return false;
112+
113+
return stepSequence
114+
.slice(0, stepIndex)
115+
.every((previousStep) => completedSteps.has(previousStep));
116+
};
117+
118+
const allRequiredStepsCompleted = stepSequence.every((step) =>
119+
completedSteps.has(step)
120+
);
105121

106122
// Handle participation type changes
107123
useEffect(() => {
@@ -168,34 +184,26 @@ const PBCTFForm: React.FC = () => {
168184

169185
setCompletedSteps(newCompletedSteps);
170186

171-
// Auto-expand next step when current step is completed
187+
// Keep only sequentially accessible sections open and expand the first
188+
// incomplete section as the user progresses.
172189
setExpandedSteps(prev => {
173-
const newExpanded = new Set(prev);
174-
175-
// Expand step 1 when step 0 is completed
176-
if (newCompletedSteps.has(0) && !newExpanded.has(1)) {
177-
newExpanded.add(1);
178-
}
179-
180-
// Expand next step when step 1 is completed
181-
if (newCompletedSteps.has(1) && !newExpanded.has(2) && !newExpanded.has(3)) {
182-
if (participationType === "solo") {
183-
newExpanded.add(3); // Skip to step 3 (additional questions) for solo participants
184-
} else {
185-
newExpanded.add(2); // Go to step 2 for duo participants
186-
}
187-
}
188-
189-
// Expand step 3 when step 2 is completed (duo only)
190-
if (participationType === "duo" && newCompletedSteps.has(2) && !newExpanded.has(3)) {
191-
newExpanded.add(3);
192-
}
193-
194-
// Expand step 4 (rules) when step 3 (additional questions) is completed
195-
if (newCompletedSteps.has(3) && !newExpanded.has(4)) {
196-
newExpanded.add(4);
190+
const sequence = participationType === "duo"
191+
? [0, 1, 2, 3, 4]
192+
: [0, 1, 3, 4];
193+
const firstIncompleteIndex = sequence.findIndex(
194+
(step) => !newCompletedSteps.has(step)
195+
);
196+
const lastAccessibleIndex =
197+
firstIncompleteIndex === -1 ? sequence.length - 1 : firstIncompleteIndex;
198+
const accessibleSteps = new Set(sequence.slice(0, lastAccessibleIndex + 1));
199+
const newExpanded = new Set(
200+
[...prev].filter((step) => accessibleSteps.has(step))
201+
);
202+
203+
if (firstIncompleteIndex !== -1) {
204+
newExpanded.add(sequence[firstIncompleteIndex]);
197205
}
198-
206+
199207
return newExpanded;
200208
});
201209
}, [
@@ -211,6 +219,8 @@ const PBCTFForm: React.FC = () => {
211219
]);
212220

213221
const handleStepClick = (stepNumber: number) => {
222+
if (!canAccessStep(stepNumber)) return;
223+
214224
setExpandedSteps(prev => {
215225
const newExpanded = new Set(prev);
216226
if (newExpanded.has(stepNumber)) {
@@ -366,6 +376,7 @@ const PBCTFForm: React.FC = () => {
366376
title="Choose Participation Mode"
367377
isCompleted={completedSteps.has(0)}
368378
isExpanded={expandedSteps.has(0)}
379+
isLocked={!canAccessStep(0)}
369380
onStepClick={handleStepClick}
370381
>
371382
<ParticipationTypeSelection
@@ -380,6 +391,7 @@ const PBCTFForm: React.FC = () => {
380391
title={participationType === 'solo' ? "Your Details" : "Team Leader Details"}
381392
isCompleted={completedSteps.has(1)}
382393
isExpanded={expandedSteps.has(1)}
394+
isLocked={!canAccessStep(1)}
383395
onStepClick={handleStepClick}
384396
>
385397
<ParticipantForm
@@ -398,6 +410,7 @@ const PBCTFForm: React.FC = () => {
398410
title="Team Member Details"
399411
isCompleted={completedSteps.has(2)}
400412
isExpanded={expandedSteps.has(2)}
413+
isLocked={!canAccessStep(2)}
401414
onStepClick={handleStepClick}
402415
>
403416
<ParticipantForm
@@ -416,6 +429,7 @@ const PBCTFForm: React.FC = () => {
416429
title="Additional Questions"
417430
isCompleted={completedSteps.has(3)}
418431
isExpanded={expandedSteps.has(3)}
432+
isLocked={!canAccessStep(3)}
419433
onStepClick={handleStepClick}
420434
>
421435
<AdditionalQuestions
@@ -432,6 +446,7 @@ const PBCTFForm: React.FC = () => {
432446
title="Rules & Agreements"
433447
isCompleted={completedSteps.has(4)}
434448
isExpanded={expandedSteps.has(4)}
449+
isLocked={!canAccessStep(4)}
435450
onStepClick={handleStepClick}
436451
>
437452
<RulesAgreements
@@ -447,7 +462,7 @@ const PBCTFForm: React.FC = () => {
447462
)}
448463

449464
{/* Submit Button */}
450-
{completedSteps.has(4) && (
465+
{allRequiredStepsCompleted && (
451466
<div className="bg-gray-900/50 border border-green-400/30 rounded-lg p-6">
452467
<button
453468
type="submit"

components/forms/pbctfForm/StepCard.tsx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ interface StepCardProps {
66
title: string;
77
isCompleted: boolean;
88
isExpanded: boolean;
9+
isLocked?: boolean;
910
children: ReactNode;
1011
onStepClick: (stepNumber: number) => void;
1112
}
@@ -15,21 +16,27 @@ const StepCard: React.FC<StepCardProps> = ({
1516
title,
1617
isCompleted,
1718
isExpanded,
19+
isLocked = false,
1820
children,
1921
onStepClick
2022
}) => {
2123
return (
2224
<div
2325
className={`
2426
relative bg-gray-900/50 border rounded-lg transition-all duration-300
25-
border-green-400/30 hover:border-green-400/50
27+
${isLocked ? 'border-gray-700 opacity-60' : 'border-green-400/30 hover:border-green-400/50'}
2628
${isExpanded ? 'ring-1 ring-green-400/50' : ''}
2729
`}
2830
>
2931
<div className="p-6">
3032
<div
31-
className={`flex items-center gap-3 cursor-pointer ${isExpanded ? 'mb-4' : 'mb-0'}`}
32-
onClick={() => onStepClick(stepNumber)}
33+
className={`flex items-center gap-3 ${
34+
isLocked ? 'cursor-not-allowed' : 'cursor-pointer'
35+
} ${isExpanded ? 'mb-4' : 'mb-0'}`}
36+
onClick={() => {
37+
if (!isLocked) onStepClick(stepNumber);
38+
}}
39+
aria-disabled={isLocked}
3340
>
3441
<div className={`
3542
w-8 h-8 rounded-full border-2 flex items-center justify-center font-mono text-sm
@@ -43,6 +50,11 @@ const StepCard: React.FC<StepCardProps> = ({
4350
{title}
4451
</h3>
4552
<div className="ml-auto flex items-center gap-2">
53+
{isLocked && (
54+
<span className="text-xs font-mono text-gray-400">
55+
LOCKED
56+
</span>
57+
)}
4658
{isCompleted && (
4759
<>
4860
<span className="hidden sm:inline-block text-xs font-mono text-green-400 bg-green-400/10 px-2 py-1 rounded border border-green-400/30">
@@ -53,7 +65,12 @@ const StepCard: React.FC<StepCardProps> = ({
5365
)}
5466
<div className={`transform transition-transform duration-300 ${isExpanded ? 'rotate-180' : ''}`}>
5567
<svg className="w-5 h-5 text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
56-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
68+
<path
69+
strokeLinecap="round"
70+
strokeLinejoin="round"
71+
strokeWidth={2}
72+
d={isLocked ? "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm3-10V7a3 3 0 016 0v4" : "M19 9l-7 7-7-7"}
73+
/>
5774
</svg>
5875
</div>
5976
</div>
@@ -72,4 +89,4 @@ const StepCard: React.FC<StepCardProps> = ({
7289
);
7390
};
7491

75-
export default StepCard;
92+
export default StepCard;

0 commit comments

Comments
 (0)