Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/components/Openings/OpeningSelectionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ const TabNavigation: React.FC<{
const { isMobile } = useContext(WindowSizeContext)

return (
<div className="flex w-full border-b border-glass-border md:hidden">
<div className="flex w-full border-b border-glass-border lg:hidden">
<button
{...(isMobile ? { id: 'opening-drill-browse' } : {})}
onClick={() => setActiveTab('browse')}
Expand Down Expand Up @@ -580,7 +580,7 @@ const BrowsePanel: React.FC<{
return (
<div
id="opening-drill-browse"
className={`flex w-full flex-col overflow-hidden ${activeTab !== 'browse' ? 'hidden md:flex' : 'flex'} md:w-[320px] md:flex-none md:border-r md:border-glass-border`}
className={`flex w-full flex-col overflow-hidden ${activeTab !== 'browse' ? 'hidden lg:flex' : 'flex'} lg:w-[320px] lg:flex-none lg:border-r lg:border-glass-border`}
>
{renderTabs()}
<form
Expand Down Expand Up @@ -761,7 +761,7 @@ const BrowsePanel: React.FC<{
return (
<div
id="opening-drill-browse"
className={`flex w-full flex-col overflow-hidden ${activeTab !== 'browse' ? 'hidden md:flex' : 'flex'} md:w-[320px] md:flex-none md:border-r md:border-glass-border`}
className={`flex w-full flex-col overflow-hidden ${activeTab !== 'browse' ? 'hidden lg:flex' : 'flex'} lg:w-[320px] lg:flex-none lg:border-r lg:border-glass-border`}
>
{renderTabs()}

Expand Down Expand Up @@ -1048,7 +1048,7 @@ const DrillStudioPanel: React.FC<{
return (
<div
id="opening-drill-preview"
className="hidden w-full flex-1 flex-col overflow-hidden md:flex"
className="hidden w-full flex-1 flex-col overflow-hidden lg:flex"
>
<div className="flex h-full flex-col border-l border-glass-border">
{/* Scrollable Content */}
Expand Down Expand Up @@ -1196,7 +1196,7 @@ const DrillStudioPanel: React.FC<{
</button>

{/* Queue */}
<div className="flex flex-col gap-3">
<div id="opening-drill-queue" className="flex flex-col gap-3">
<div className="flex items-center justify-between">
<p className="text-[12px] font-semibold uppercase tracking-[0.12em] text-white/35">
Queue
Expand Down Expand Up @@ -1308,7 +1308,7 @@ const SelectedPanel: React.FC<{
showTargetSlider,
}) => (
<div
id="opening-drill-selected"
id="opening-drill-selected-panel"
className={`flex w-full flex-col overflow-hidden ${activeTab !== 'selected' ? 'hidden' : 'flex'}`}
>
<div className="flex h-16 flex-col justify-center gap-1 border-b border-glass-border p-4">
Expand Down Expand Up @@ -2648,7 +2648,7 @@ export const OpeningSelectionModal: React.FC<Props> = ({
/>

{/* Main Content - Responsive Layout */}
<div className="grid w-full flex-1 grid-cols-1 overflow-hidden md:grid-cols-[320px_minmax(0,1fr)]">
<div className="grid w-full flex-1 grid-cols-1 overflow-hidden lg:grid-cols-[320px_minmax(0,1fr)]">
<BrowsePanel
activeTab={activeTab}
filteredOpenings={filteredOpenings}
Expand Down Expand Up @@ -2723,7 +2723,7 @@ export const OpeningSelectionModal: React.FC<Props> = ({
</div>

{/* Mobile-only Selected Panel */}
<div className="w-full md:hidden">
<div className="w-full lg:hidden">
<SelectedPanel
activeTab={activeTab}
selections={selections}
Expand Down
85 changes: 50 additions & 35 deletions src/constants/tours.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,40 +135,55 @@ export const handBrainTourSteps: TourStep[] = [
},
]

export const openingDrillTourSteps: TourStep[] = [
{
id: 'opening-drill-overview',
title: 'Welcome to Opening Drills',
description:
'Practice your openings by drilling specific openings against Maia. First select the openings you want to practice, configure drill settings, and practice them repeatedly until they become second nature. You can track your progress and analyze your performance after each drill.',
targetId: 'opening-drill-modal',
placement: 'bottom',
},
{
id: 'opening-drill-selection',
title: 'Select Openings',
description:
'Browse and select the openings you want to practice. You can search for specific variations and add them using the + button.',
targetId: 'opening-drill-browse',
placement: 'right',
},
{
id: 'opening-drill-start',
title: 'Start Drilling',
description:
'Customize your drills by choosing the Maia opponent strength, how many moves in each drill, and how many drills to do. Click "Start Drilling" to start!',
targetId: 'opening-drill-selected',
placement: 'left',
},
{
id: 'opening-drill-gameplay',
title: 'Drill Experience',
description:
"During drilling, you'll play through your selected openings against Maia until reaching the target move count. After each drill, you can analyze the moves you played, see how the Maia and Stockfish evaluations changed throughout the game, and learn from your insights.",
targetId: 'opening-drill-modal',
placement: 'bottom',
},
]
const clickTab = (id: string) => () => {
document
.getElementById(id)
?.dispatchEvent(new MouseEvent('click', { bubbles: true }))
}

const openingDrillTourSteps = (): TourStep[] => {
const isMobile = typeof window !== 'undefined' && window.innerWidth < 1024

return [
{
id: 'opening-drill-overview',
title: 'Welcome to Opening Drills',
description:
'Practice your openings by drilling specific openings against Maia. First select the openings you want to practice, configure drill settings, and practice them repeatedly until they become second nature. You can track your progress and analyze your performance after each drill.',
targetId: 'opening-drill-modal',
placement: 'bottom',
},
{
id: 'opening-drill-selection',
title: 'Select Openings',
description:
'Browse and select the openings you want to practice. You can search for specific variations and add them using the + button.',
targetId: 'opening-drill-browse',
placement: isMobile ? 'bottom' : 'right',
...(isMobile && { beforeAction: clickTab('opening-drill-browse') }),
},
{
id: 'opening-drill-start',
title: 'Start Drilling',
description:
'Customize your drills by choosing the Maia opponent strength, how many moves in each drill, and how many drills to do. Click "Start Drilling" to start!',
targetId: isMobile ? 'opening-drill-selected' : 'opening-drill-preview',
placement: isMobile ? 'bottom' : 'left',
...(isMobile && { beforeAction: clickTab('opening-drill-selected') }),
},
{
id: 'opening-drill-gameplay',
title: 'Drill Experience',
description:
"During drilling, you'll play through your selected openings against Maia until reaching the target move count. After each drill, you can analyze the moves you played, see how the Maia and Stockfish evaluations changed throughout the game, and learn from your insights.",
targetId: isMobile
? 'opening-drill-selected-panel'
: 'opening-drill-queue',
placement: isMobile ? 'bottom' : 'left',
...(isMobile && { beforeAction: clickTab('opening-drill-selected') }),
},
]
}

export const tourConfigs = {
analysis: {
Expand Down Expand Up @@ -199,6 +214,6 @@ export const tourConfigs = {
openingDrill: {
id: 'openingDrill',
name: 'Opening Drill Tour',
steps: openingDrillTourSteps,
steps: openingDrillTourSteps(),
},
}
13 changes: 11 additions & 2 deletions src/contexts/TourContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface TourStep {
targetId: string
placement?: 'top' | 'bottom' | 'left' | 'right'
offset?: { x: number; y: number }
beforeAction?: () => void | Promise<void>
}

export interface TourState {
Expand Down Expand Up @@ -497,14 +498,18 @@ export const TourProvider: React.FC<TourProviderProps> = ({ children }) => {
const handleNext = useCallback(async () => {
if (tourState.currentStep < tourState.steps.length - 1) {
const nextStepIndex = tourState.currentStep + 1
const nextStepData = tourState.steps[nextStepIndex]
if (nextStepData?.beforeAction) {
await nextStepData.beforeAction()
}
await preScrollToTarget(nextStepIndex)
nextStep()
} else {
endTour()
}
}, [
tourState.currentStep,
tourState.steps.length,
tourState.steps,
nextStep,
endTour,
preScrollToTarget,
Expand All @@ -513,10 +518,14 @@ export const TourProvider: React.FC<TourProviderProps> = ({ children }) => {
const handlePrevious = useCallback(async () => {
if (tourState.currentStep > 0) {
const prevStepIndex = tourState.currentStep - 1
const prevStepData = tourState.steps[prevStepIndex]
if (prevStepData?.beforeAction) {
await prevStepData.beforeAction()
}
await preScrollToTarget(prevStepIndex)
prevStep()
}
}, [tourState.currentStep, prevStep, preScrollToTarget])
}, [tourState.currentStep, tourState.steps, prevStep, preScrollToTarget])

// Update Joyride steps when tour state changes
useEffect(() => {
Expand Down