# Frontend Integration Guide (Nuxt.js / Next.js)

## 🎯 Architecture

```
Frontend (Nuxt/Next.js)          Backend (Django)
Port: 3000                       Port: 8000
├── Pages/Routes                 ├── API Endpoints
├── UI/UX                        ├── Authentication
├── API Calls                    ├── Database
└── Token Storage                └── Business Logic
```

---

## 📧 Email Links Flow

### How It Works:

1. **User registers** → Backend sends email
2. **Email contains** → Frontend URL (http://localhost:3000/activate/...)
3. **User clicks link** → Opens Frontend page
4. **Frontend JavaScript** → Calls Backend API
5. **Backend** → Activates account, returns response
6. **Frontend** → Shows success message

### Email Link Format:

```
Activation: http://localhost:3000/activate/{uid}/{token}/
Password Reset: http://localhost:3000/password-reset/{uid}/{token}/
```

---

## 🚀 Nuxt.js Implementation

### 1. Environment Variables (`.env`)

```bash
# Nuxt.js .env
NUXT_PUBLIC_API_BASE=http://localhost:8000/api/v1
```

### 2. Nuxt Config (`nuxt.config.ts`)

```typescript
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      apiBase: process.env.NUXT_PUBLIC_API_BASE || 'http://localhost:8000/api/v1'
    }
  },
  
  // CORS configuration for development
  nitro: {
    devProxy: {
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true
      }
    }
  }
})
```

### 3. API Composable (`composables/useApi.ts`)

```typescript
export const useApi = () => {
  const config = useRuntimeConfig()
  const apiBase = config.public.apiBase

  return {
    apiBase,
    
    async fetch(endpoint: string, options: any = {}) {
      return await $fetch(`${apiBase}${endpoint}`, options)
    }
  }
}
```

### 4. Auth Composable (`composables/useAuth.ts`)

```typescript
export const useAuth = () => {
  const { apiBase } = useApi()
  const router = useRouter()
  
  // Register
  const register = async (userData: {
    email: string
    password: string
    re_password: string
    first_name: string
    last_name: string
  }) => {
    return await $fetch(`${apiBase}/auth/users/`, {
      method: 'POST',
      body: userData
    })
  }
  
  // Activate Account
  const activate = async (uid: string, token: string) => {
    return await $fetch(`${apiBase}/auth/users/activation/`, {
      method: 'POST',
      body: { uid, token }
    })
  }
  
  // Login
  const login = async (email: string, password: string) => {
    const data = await $fetch(`${apiBase}/auth/jwt/create/`, {
      method: 'POST',
      body: { email, password }
    })
    
    // Save tokens
    localStorage.setItem('access_token', data.access)
    localStorage.setItem('refresh_token', data.refresh)
    
    return data
  }
  
  // Social Login
  const socialLogin = async (provider: string, accessToken: string) => {
    const data = await $fetch(`${apiBase}/auth/social/${provider}/`, {
      method: 'POST',
      body: { access_token: accessToken }
    })
    
    // Save JWT tokens
    localStorage.setItem('access_token', data.access)
    localStorage.setItem('refresh_token', data.refresh)
    
    return data
  }
  
  // Get Current User
  const getUser = async () => {
    const token = localStorage.getItem('access_token')
    if (!token) return null
    
    return await $fetch(`${apiBase}/auth/users/me/`, {
      headers: {
        Authorization: `Bearer ${token}`
      }
    })
  }
  
  // Logout
  const logout = () => {
    localStorage.removeItem('access_token')
    localStorage.removeItem('refresh_token')
    router.push('/login')
  }
  
  return {
    register,
    activate,
    login,
    socialLogin,
    getUser,
    logout
  }
}
```

### 5. Activation Page (`pages/activate/[uid]/[token].vue`)

```vue
<template>
  <div class="activation-page">
    <div v-if="loading" class="loading">
      <div class="spinner"></div>
      <h1>Activating Your Account...</h1>
      <p>Please wait while we activate your account.</p>
    </div>
    
    <div v-else-if="success" class="success">
      <div class="icon">✅</div>
      <h1>Account Activated!</h1>
      <p>Your account has been successfully activated.</p>
      <NuxtLink to="/login" class="btn">Go to Login</NuxtLink>
    </div>
    
    <div v-else class="error">
      <div class="icon">❌</div>
      <h1>Activation Failed</h1>
      <p>{{ error }}</p>
      <NuxtLink to="/login" class="btn">Back to Login</NuxtLink>
    </div>
  </div>
</template>

<script setup lang="ts">
const route = useRoute()
const { activate } = useAuth()

const loading = ref(true)
const success = ref(false)
const error = ref('')

onMounted(async () => {
  const uid = route.params.uid as string
  const token = route.params.token as string
  
  try {
    await activate(uid, token)
    success.value = true
  } catch (e: any) {
    error.value = e.data?.detail || e.data?.token?.[0] || 'Activation failed'
  } finally {
    loading.value = false
  }
})
</script>

<style scoped>
.activation-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}

.spinner {
  border: 4px solid #f3f3f3;
  border-top: 4px solid #667eea;
  border-radius: 50%;
  width: 60px;
  height: 60px;
  animation: spin 1s linear infinite;
  margin: 0 auto 2rem;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
</style>
```

### 6. Register Page (`pages/register.vue`)

```vue
<template>
  <div class="register-page">
    <div class="card">
      <h1>Create Account</h1>
      
      <form @submit.prevent="handleRegister">
        <input v-model="form.email" type="email" placeholder="Email" required />
        <input v-model="form.first_name" placeholder="First Name" required />
        <input v-model="form.last_name" placeholder="Last Name" required />
        <input v-model="form.password" type="password" placeholder="Password" required />
        <input v-model="form.re_password" type="password" placeholder="Confirm Password" required />
        <button type="submit">Register</button>
      </form>
      
      <div v-if="registered" class="success">
        ✅ Registration successful! Please check your email to activate your account.
      </div>
      
      <div v-if="error" class="error">{{ error }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
const { register } = useAuth()

const form = ref({
  email: '',
  password: '',
  re_password: '',
  first_name: '',
  last_name: ''
})

const registered = ref(false)
const error = ref('')

const handleRegister = async () => {
  try {
    await register(form.value)
    registered.value = true
  } catch (e: any) {
    error.value = Object.values(e.data).flat().join(', ')
  }
}
</script>
```

### 7. Login Page (`pages/login.vue`)

```vue
<template>
  <div class="login-page">
    <div class="card">
      <h1>Login</h1>
      
      <form @submit.prevent="handleLogin">
        <input v-model="email" type="email" placeholder="Email" required />
        <input v-model="password" type="password" placeholder="Password" required />
        <button type="submit">Login</button>
      </form>
      
      <div class="divider">OR</div>
      
      <button @click="loginWithGoogle" class="btn-google">
        Continue with Google
      </button>
      
      <div v-if="error" class="error">{{ error }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
const { login, socialLogin } = useAuth()
const router = useRouter()

const email = ref('')
const password = ref('')
const error = ref('')

const handleLogin = async () => {
  try {
    await login(email.value, password.value)
    router.push('/dashboard')
  } catch (e: any) {
    error.value = e.data?.detail || 'Login failed'
  }
}

const loginWithGoogle = async () => {
  // Implement Google OAuth (use @nuxtjs/google-oauth2 or similar)
  const googleToken = await getGoogleAccessToken()
  
  try {
    await socialLogin('google-oauth2', googleToken)
    router.push('/dashboard')
  } catch (e: any) {
    error.value = e.data?.error || 'Social login failed'
  }
}
</script>
```

---

## 🔐 Protected Pages (Middleware)

### Auth Middleware (`middleware/auth.ts`)

```typescript
export default defineNuxtRouteMiddleware((to, from) => {
  const token = process.client ? localStorage.getItem('access_token') : null
  
  if (!token) {
    return navigateTo('/login')
  }
})
```

### Dashboard Page (`pages/dashboard.vue`)

```vue
<template>
  <div class="dashboard">
    <h1>Welcome, {{ user?.first_name }}!</h1>
    <p>Email: {{ user?.email }}</p>
    <button @click="logout">Logout</button>
  </div>
</template>

<script setup lang="ts">
definePageMeta({
  middleware: 'auth'
})

const { getUser, logout } = useAuth()
const user = ref(null)

onMounted(async () => {
  user.value = await getUser()
})
</script>
```

---

## 🌐 Next.js Implementation

Very similar to Nuxt.js, just adjust the syntax:

```typescript
// app/activate/[uid]/[token]/page.tsx
'use client'

import { useEffect, useState } from 'react'
import { useParams, useRouter } from 'next/navigation'

export default function ActivatePage() {
  const params = useParams()
  const [loading, setLoading] = useState(true)
  const [success, setSuccess] = useState(false)
  const [error, setError] = useState('')
  
  useEffect(() => {
    const activate = async () => {
      try {
        const response = await fetch(
          `${process.env.NEXT_PUBLIC_API_BASE}/auth/users/activation/`,
          {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              uid: params.uid,
              token: params.token
            })
          }
        )
        
        if (response.ok) {
          setSuccess(true)
        } else {
          const data = await response.json()
          setError(data.detail || 'Activation failed')
        }
      } catch (e) {
        setError('Network error')
      } finally {
        setLoading(false)
      }
    }
    
    activate()
  }, [params])
  
  if (loading) return <div>Activating...</div>
  if (success) return <div>✅ Account Activated!</div>
  return <div>❌ {error}</div>
}
```

---

## 📝 Summary

### Email Links:
- Activation: `http://localhost:3000/activate/{uid}/{token}/`
- Password Reset: `http://localhost:3000/password-reset/{uid}/{token}/`

### API Endpoints (Backend):
- Register: `POST http://localhost:8000/api/v1/auth/users/`
- Activate: `POST http://localhost:8000/api/v1/auth/users/activation/`
- Login: `POST http://localhost:8000/api/v1/auth/jwt/create/`
- Social Login: `POST http://localhost:8000/api/v1/auth/social/{provider}/`
- Current User: `GET http://localhost:8000/api/v1/auth/users/me/`

### Production URLs:
- Frontend: `https://yourdomain.com`
- Backend: `https://api.yourdomain.com`

Update `DOMAIN` in Django settings for production!

---

**Happy Coding! 🚀**

