Skip to main content

Book Your First Class in 5 Steps

This guide will walk you through creating your account, setting up your profile, and booking your first English lesson on the Speak English Now platform.
1

Sign In with OAuth

The platform uses NextAuth for secure authentication with Google and GitHub providers.
import { signIn } from "next-auth/react"

// The Google OAuth button
<GoogleButton
  onClick={() => signIn('google', { callbackUrl: '/inicio' })}
  label="Inicia Sesion"
/>
When you click the sign-in button:
  1. You’ll be redirected to Google’s OAuth consent screen
  2. Grant calendar permissions for class scheduling
  3. Automatically redirected to /inicio (your dashboard)
The platform requests Google Calendar permissions (calendar.events scope) to automatically create class events and generate Meet links.

What Happens Behind the Scenes

// From auth.ts
export const { handlers, signIn, signOut, auth } = NextAuth({
  providers: [Google({
    authorization: {
      params: {
        scope: "openid email profile https://www.googleapis.com/auth/calendar.events",
        access_type: "offline",
      }
    }
  })],
  callbacks: {
    async signIn({ user, account, profile }) {
      const { name, email, image } = user
      const userFound = await loggedAsAdmin(email)
      
      if (!userFound) {
        await createUser(name, email, image)
      }
      return true
    }
  }
})
Your user record is created in the database with default values:
// From server-actions/actions.ts
const newUser = await db.user.create({
  data: {
    name,
    email,
    image,
    nivel: "inicial",           // Default English level
    totalClasses: 0,           // Classes completed
    newsletter: "no",          // Newsletter preference
    status: false              // Account status
  }
})
2

Complete Your Profile

Navigate to Configuración (Settings) to set up your learning profile.

Required Information

Update your profile with:
  • Nivel de Inglés: Choose from inicial, básico, intermedio, or avanzado
  • Localidad: Your city/location
  • Teléfono: Contact number for notifications
  • Newsletter: Opt in/out of learning tips and updates
// User profile update from services/functions/index.ts
await db.user.update({
  where: { id },
  data: {
    localidad: "Buenos Aires",
    nivel: "intermedio",
    telefono: 1130577799,
    newsletter: "si"
  }
})
Your English level determines which learning track you’ll be assigned:
  • Inicial: Grammar-focused classes
  • Intermedio: Listening and comprehension
  • Avanzado: Conversational fluency
3

Browse Available Classes

Go to Calendario or Reservas to view available time slots.

Understanding the Calendar

The platform uses FullCalendar to display real-time availability:
// From inicio/reservas/page.tsx
<FullCalendar
  allDaySlot={false}
  initialView="timeGridWeek"
  slotMinTime="17:00:00"
  slotMaxTime="21:00:00"
  slotDuration="01:00:00"
  businessHours={{
    startTime: '17:00',
    endTime: '21:00',
    daysOfWeek: [1, 2, 3, 4, 5, 6]
  }}
  dateClick={(info) => {
    scheduleClass({ info, setOpen, setSelectedDate })
    const start = new Date(info.date)
    const end = new Date(start.getTime() + 60 * 60 * 1000)
    setScheduledTime({ start, end })
  }}
/>

Class Status Indicators

  • Yellow (Reservada): Scheduled and confirmed
  • Gray (Completada): Class finished
  • Disabled: Past dates or unavailable slots
You can only book classes from today onwards. Past dates are automatically disabled in the calendar interface.
4

Configure Your Class

After selecting a time slot, configure your class details in the Detalles de la reserva section.

Choose Class Type

Individual Class (1 student)
  • Personalized attention
  • Custom learning objectives
  • Base price: Check pricing.json
Group Class (2-5 students)
  • Collaborative learning
  • Reduced per-student pricing
  • Select number of participants
// Dynamic pricing calculation
const handleClassTypeChange = (e) => {
  const isGroup = e.target.value === "grupal"
  
  if (e.target.value === "individual") {
    setStudentsCount(1)
    setPrice(pricing.basePrice)
  }
  
  setClassMetadata({
    type: isGroup ? "grupal" : "individual",
    studentsCount: isGroup ? studentsCount : 1,
    price: isGroup ? pricing.perStudent[studentsCount] : pricing.basePrice
  })
}

Set Learning Focus

Describe your learning objective in the Objetivo de la clase textarea (max 100 characters):
<Textarea
  maxLength={100}
  placeholder='Describe el tema que necesitas tratar durante la clase (opcional)...'
  value={text}
  onChange={(e) => setText(e.target.value)}
/>
Examples:
  • “Practice business English presentations”
  • “Improve pronunciation of difficult words”
  • “Learn travel vocabulary and phrases”
While the learning focus is optional, providing specific goals helps your instructor prepare relevant materials.
5

Complete Payment & Confirm

Click Agendar clase to proceed to payment.

Payment Flow

  1. Create Mercado Pago Preference
// Create payment preference
const preferenceData = {
  items: [{
    title: `Clase ${classType}`,
    quantity: 1,
    unit_price: price
  }],
  back_urls: {
    success: `${baseUrl}/checkout/callback/success`,
    failure: `${baseUrl}/checkout/callback/failure`,
    pending: `${baseUrl}/checkout/callback/pending`
  }
}
  1. Create Pending Virtual Class
Once payment is initiated, a class record is created with status: "pending":
// From api/booking/route.ts
const bookingData = {
  start: scheduledTime.start,
  end: scheduledTime.end,
  classType: isGroupClass ? "grupal" : "individual",
  classPrice: Number(price),
  maxParticipants: isGroupClass ? studentsCount : 1,
  preferenceId: mpPreferenceId,
  learningFocus: text
}

await createVirtualClass(bookingData, userId)
  1. Payment Confirmation
After successful payment, the webhook updates the class:
// Webhook updates class status to "scheduled"
await db.virtualClass.update({
  where: { preferenceId },
  data: {
    status: "scheduled",
    googleEventId: calendarEvent.id,
    htmlLink: calendarEvent.hangoutLink,
    accessCode: generateAccessCode()
  }
})

What You’ll Receive

Email Confirmation

Payment receipt and class details from Mercado Pago

Calendar Event

Automatic Google Calendar invite with Meet link

Access Code

Unique code to join class (available 60 min before start)

Activity Assignment

AI-generated post-class exercises in “Mis Actividades”
Your class is confirmed only when payment status changes to approved. Pending or rejected payments will not create calendar events.

Accessing Your Class

60 Minutes Before Start Time

Navigate to Mis Clases Virtuales to view your upcoming classes and access codes.
// Access code component from mis-clases-virtuales/AccessCode.tsx
<Card>
  <h3>Código de Acceso</h3>
  <p className="text-2xl font-mono">{accessCode}</p>
  <Button onClick={() => window.open(htmlLink)}>
    Unirse a la Clase
  </Button>
</Card>
The Unirse a la Clase button appears when:
  • Current time is within 60 minutes of class start
  • Class status is scheduled
  • You have a valid accessCode

During the Class

  1. Click the join button to open Google Meet
  2. Enter your access code if prompted
  3. Participate in the 90-minute session
  4. Take notes on topics covered

After the Class

Check Mis Actividades for AI-generated exercises based on your lesson:
// AI tutor creates activities
const userActivity = await db.userActivity.create({
  data: {
    userId: user.id,
    classId: class.id,
    taskId: aiGeneratedTask.id,
    rol: "participante",
    completed: false
  }
})
Activity types:
  • exam: Multiple choice or written tests
  • audio: Listening comprehension
  • video: Video analysis tasks
  • reading: Text comprehension
Activities must be completed before your next class to track progress effectively. The AI tutor adjusts difficulty based on your performance.

Troubleshooting

Access codes appear 60 minutes before class start. If your class is within this window and you don’t see it, check that:
  • Payment status is approved (check Facturación)
  • Class status is scheduled (not pending or cancelled)
  • You’re logged in with the correct account
The webhook might have failed. Contact support via Centro de Ayuda with your:
  • User ID (from Configuración)
  • Preference ID (from payment confirmation)
  • Payment date and time
Currently, cancellations and rescheduling must be done through support. Submit a ticket at Centro de Ayuda with category “CUENTA” or contact via WhatsApp: +11-3057-7799

Next Steps

Explore Learning Levels

Learn about Grammar, Listening, and Conversational tracks

API Reference

Integrate with the platform API for custom solutions

Virtual Classes

Discover individual and group class formats

Learning Activities

Explore AI-powered exams and exercises

Need Help?

Support Tickets

Submit a support ticket for assistance. Average response time: 24 hours
For urgent issues during class time, contact via WhatsApp: +11-3057-7799

Build docs developers (and LLMs) love