BeYourMotorbike

Motorcycle Rental Platform in Tenerife

The Challenge

I developed a complete motorcycle rental platform from scratch using Next.js 15 with TypeScript, PostgreSQL and Prisma ORM. The project includes a robust authentication system with NextAuth.js, payment processing with Stripe (including deposits, automatic commissions and refunds), and a complete administrative panel for user, booking and analytics management.

Tech Stack

Frontend

Next.js 15
TypeScript
Tailwind CSS
Framer Motion
Leaflet

Backend

Prisma ORM
NextAuth.js
Stripe
Zod

Database

PostgreSQL

Tools

Cloudinary
next-intl

Technical Challenges Overcome

Database Design from Scratch

Challenge:

First time designing a complete relational schema for a marketplace with multiple interconnected entities.

Solution:

I created 8+ interconnected tables with complex relationships between users, motorcycles, bookings and payments. I implemented granular roles (CLIENT, PROVIDER, ADMIN) and a scalable document system.

Result:

Scalable system that efficiently handles all marketplace operations with complete referential integrity.

Complex Payment System

Challenge:

Integrate Stripe with automatic commission calculations, deposits, discounts and refunds.

Solution:

I implemented webhooks to process payments in real time, calculate automatic commissions, handle 15% initial deposits and a complete refund system with tracking.

Result:

Automatic payment system that processes transactions securely with precise financial calculations.

Enterprise Internationalization

Challenge:

Create a multi-language platform with optimized SEO for three different markets.

Solution:

I implemented next-intl with complete support for ES/EN/DE, configured hreflang for SEO, and created intelligent middleware for automatic redirection based on browser language.

Result:

Completely internationalized platform with optimized SEO for three languages and fluid UX.

Featured Functionalities

Advanced Document System

Allows scanning documents with mobile camera, cropping them with CropperJS and uploading them organized to Cloudinary. Includes ITV, insurance and license validation with access tokens for secure viewing.

Complete Administrative Panel

Panel with user, motorcycle, booking and real-time analytics management. Includes marketing system with data export and refund management with states.

Automatic Payment Processing

Complete Stripe integration that handles deposits (15% initial), automatic commission calculation, discount codes and refunds with complete tracking.

Smart Booking System

Dynamic calendars with real-time availability, automatic price calculation by duration, discount application and extras management (helmets, jackets, etc.).

Project Results

2 months
Development Time
8+
Database Tables
3
Languages Implemented
15+
API Endpoints
100%
Type Safety
6
Admin Panel Sections

Featured Code

JWT with Automatic Renewal and User Validation

Advanced JWT system with automatic user verification in database and proactive token renewal to maintain secure sessions.

// JWT with automatic renewal and user validation
async jwt({ token, user }) {
  if (user) {
    token.id = user.id;
    token.role = user.role;
    token.iat = Math.floor(Date.now() / 1000);
    token.exp = Math.floor(Date.now() / 1000) + 24 * 60 * 60;
  }

  // Verify user exists in database
  if (token.id) {
    try {
      const userExists = await prisma.user.findUnique({
        where: { id: token.id as string },
        select: { id: true, role: true },
      });

      if (!userExists) {
        return { ...token, error: "UserNotFound" };
      }

      token.role = userExists.role;
    } catch (error) {
      console.error("Error verifying user existence:", error);
      return { ...token, error: "UserVerificationFailed" };
    }
  }

  // Renew token if expiring soon (2 hours before)
  if (
    token.exp &&
    typeof token.exp === "number" &&
    token.exp < Math.floor(Date.now() / 1000) + 2 * 60 * 60
  ) {
    token.exp = Math.floor(Date.now() / 1000) + 24 * 60 * 60;
  }

  return token;
}

Document System with Validation

Robust document validation with Zod to ensure data integrity before upload.

// Document system with validation
const documentSchema = z.object({
  documentType: z.enum(['id', 'license', 'itv', 'insurance']),
  side: z.enum(['front', 'back']),
  file: z.instanceof(File),
  expiryDate: z.date().optional()
});
Cristian Perdomo - Desarrollador Full Stack