# ⚡ Next.js Migration - Quick Start Guide

## 🎯 Goal
Get a working Next.js version of PLAGIS running in **1 hour**

---

## 📋 Prerequisites

### 1. Check Node.js Version
```bash
node --version  # Should be v18.0.0 or higher
npm --version   # Should be 9.0.0 or higher
```

If not installed:
```bash
# Download from https://nodejs.org/
# Or use nvm (recommended):
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install 18
nvm use 18
```

---

## 🚀 Step-by-Step Setup

### Step 1: Create Next.js Project (5 minutes)

```bash
# Navigate to workspace
cd /home/plagis/workspace/plagis_aumentum

# Create Next.js app
npx create-next-app@latest plagis-nextjs \
  --typescript \
  --tailwind \
  --app \
  --src-dir \
  --import-alias "@/*" \
  --no-eslint
```

**Answer the prompts:**
```
✔ Would you like to use TypeScript? Yes
✔ Would you like to use ESLint? No (we'll add later)
✔ Would you like to use Tailwind CSS? Yes
✔ Would you like to use `src/` directory? Yes
✔ Would you like to use App Router? Yes
✔ Would you like to customize the default import alias? Yes (@/*)
```

### Step 2: Install Additional Dependencies (2 minutes)

```bash
cd plagis-nextjs

# Install core libraries
npm install axios zustand @tanstack/react-query date-fns

# Install UI components (optional - for nice UI)
npm install lucide-react class-variance-authority clsx tailwind-merge
```

### Step 3: Create Environment Variables (1 minute)

```bash
# Create .env.local file
cat > .env.local << 'EOF'
NEXT_PUBLIC_API_URL=http://localhost:8001
EOF
```

### Step 4: Update Next.js Config (2 minutes)

Create/update `next.config.js`:
```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
  // Standalone build for production
  output: 'standalone',
  
  // API proxy to avoid CORS issues
  async rewrites() {
    return [
      {
        source: '/api/:path*',
        destination: 'http://localhost:8001/:path*',
      },
    ]
  },
  
  // Image domains (if needed)
  images: {
    domains: ['localhost'],
  },
}

module.exports = nextConfig
```

### Step 5: Create Basic Structure (10 minutes)

```bash
# Create folder structure
mkdir -p src/lib
mkdir -p src/components/auth
mkdir -p src/components/ui
mkdir -p src/app/login
mkdir -p src/app/dashboard
mkdir -p src/hooks
mkdir -p src/types
```

### Step 6: Create API Client (5 minutes)

Create `src/lib/api.ts`:
```typescript
import axios from 'axios';

const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8001';

// Create axios instance
export const apiClient = axios.create({
  baseURL: API_BASE_URL,
  headers: {
    'Content-Type': 'application/json',
  },
});

// Request interceptor - add auth token
apiClient.interceptors.request.use((config) => {
  if (typeof window !== 'undefined') {
    const token = localStorage.getItem('access_token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
  }
  return config;
});

// Response interceptor - handle 401
apiClient.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.response?.status === 401 && typeof window !== 'undefined') {
      localStorage.clear();
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);

// Auth API
export const authApi = {
  login: async (username: string, password: string) => {
    const formData = new URLSearchParams();
    formData.append('username', username);
    formData.append('password', password);
    
    const response = await axios.post(`${API_BASE_URL}/auth/login`, formData, {
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    });
    return response.data;
  },
  
  logout: async () => {
    return apiClient.post('/auth/logout');
  },
  
  getCurrentUser: async () => {
    const response = await apiClient.get('/auth/me');
    return response.data;
  },
};
```

### Step 7: Create TypeScript Types (3 minutes)

Create `src/types/index.ts`:
```typescript
export interface User {
  id: number;
  username: string;
  full_name: string;
  role: string;
}

export interface LoginResponse {
  access_token: string;
  token_type: string;
  user: User;
}

export interface Transaction {
  id: number;
  transaction_number: string;
  transaction_type: string;
  transaction_type_label: string;
  transaction_status_label: string;
  application_date?: string;
  complete_date?: string;
  instrument_number?: string;
  page_number?: string;
  volume?: string;
  old_property_id?: string;
  target_property_ids?: string;
  source_property_ids?: string;
}
```

### Step 8: Create Login Page (10 minutes)

Create `src/app/login/page.tsx`:
```typescript
'use client';

import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { authApi } from '@/lib/api';

export default function LoginPage() {
  const router = useRouter();
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setError('');
    setLoading(true);

    try {
      const data = await authApi.login(username, password);
      
      // Store token and user info
      localStorage.setItem('access_token', data.access_token);
      localStorage.setItem('user_info', JSON.stringify(data.user));
      
      // Redirect to dashboard
      router.push('/dashboard');
    } catch (err: any) {
      setError(err.response?.data?.detail || 'Login failed');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="min-h-screen bg-gradient-to-br from-emerald-700 to-emerald-900 flex items-center justify-center p-4">
      <div className="bg-white/20 backdrop-blur-xl rounded-3xl shadow-2xl w-full max-w-md p-8 border border-white/30">
        <div className="text-center mb-8">
          <h1 className="text-3xl font-bold text-white mb-2">📁 PLAGIS</h1>
          <p className="text-white/80">Land Registry Document System</p>
        </div>

        <form onSubmit={handleSubmit} className="space-y-6">
          {error && (
            <div className="bg-red-100 text-red-700 p-3 rounded-lg text-sm">
              {error}
            </div>
          )}

          <div>
            <label className="block text-white/90 text-sm font-semibold mb-2">
              Username
            </label>
            <input
              type="text"
              value={username}
              onChange={(e) => setUsername(e.target.value)}
              className="w-full px-4 py-3 rounded-lg bg-white/80 backdrop-blur border-2 border-white/50 focus:border-emerald-500 focus:outline-none transition"
              placeholder="Enter your username"
              required
            />
          </div>

          <div>
            <label className="block text-white/90 text-sm font-semibold mb-2">
              Password
            </label>
            <input
              type="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              className="w-full px-4 py-3 rounded-lg bg-white/80 backdrop-blur border-2 border-white/50 focus:border-emerald-500 focus:outline-none transition"
              placeholder="Enter your password"
              required
            />
          </div>

          <button
            type="submit"
            disabled={loading}
            className="w-full py-3 bg-gradient-to-r from-emerald-600 to-emerald-700 text-white font-semibold rounded-lg shadow-lg hover:shadow-xl hover:-translate-y-0.5 transition disabled:opacity-50"
          >
            {loading ? 'Signing in...' : 'Sign In'}
          </button>
        </form>

        <div className="mt-6 text-center text-white/60 text-sm">
          Plateau State Geographic Information Service
        </div>
      </div>
    </div>
  );
}
```

### Step 9: Create Dashboard Page (5 minutes)

Create `src/app/dashboard/page.tsx`:
```typescript
'use client';

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

export default function DashboardPage() {
  const router = useRouter();
  const [user, setUser] = useState<any>(null);

  useEffect(() => {
    // Check authentication
    const token = localStorage.getItem('access_token');
    const userInfo = localStorage.getItem('user_info');
    
    if (!token || !userInfo) {
      router.push('/login');
      return;
    }
    
    setUser(JSON.parse(userInfo));
  }, [router]);

  const handleLogout = () => {
    localStorage.clear();
    router.push('/login');
  };

  if (!user) {
    return (
      <div className="min-h-screen flex items-center justify-center">
        <div className="text-gray-600">Loading...</div>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-gray-50">
      {/* Header */}
      <header className="bg-white shadow-sm">
        <div className="max-w-7xl mx-auto px-4 py-4 flex justify-between items-center">
          <div>
            <h1 className="text-2xl font-bold text-gray-900">📁 PLAGIS</h1>
            <p className="text-sm text-gray-600">Dashboard</p>
          </div>
          <div className="flex items-center gap-4">
            <div className="text-right">
              <div className="font-semibold">{user.full_name}</div>
              <div className="text-sm text-gray-600">{user.role}</div>
            </div>
            <button
              onClick={handleLogout}
              className="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition"
            >
              Logout 🚪
            </button>
          </div>
        </div>
      </header>

      {/* Main Content */}
      <main className="max-w-7xl mx-auto px-4 py-8">
        <div className="bg-white rounded-lg shadow-sm p-8">
          <h2 className="text-xl font-bold mb-4">Welcome to PLAGIS Next.js!</h2>
          <p className="text-gray-600 mb-4">
            This is the new Next.js version of PLAGIS. We'll migrate all features here.
          </p>
          
          <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mt-8">
            <div className="p-6 bg-emerald-50 rounded-lg">
              <h3 className="font-bold text-emerald-900 mb-2">Transactions</h3>
              <p className="text-sm text-emerald-700">Search and view transactions</p>
            </div>
            <div className="p-6 bg-blue-50 rounded-lg">
              <h3 className="font-bold text-blue-900 mb-2">Documents</h3>
              <p className="text-sm text-blue-700">Browse document registry</p>
            </div>
            <div className="p-6 bg-purple-50 rounded-lg">
              <h3 className="font-bold text-purple-900 mb-2">Properties</h3>
              <p className="text-sm text-purple-700">View property information</p>
            </div>
          </div>
        </div>
      </main>
    </div>
  );
}
```

### Step 10: Update Root Page (2 minutes)

Update `src/app/page.tsx`:
```typescript
'use client';

import { useEffect } from 'react';
import { useRouter } from 'next/navigation';

export default function Home() {
  const router = useRouter();

  useEffect(() => {
    // Redirect to login or dashboard based on auth
    const token = localStorage.getItem('access_token');
    if (token) {
      router.push('/dashboard');
    } else {
      router.push('/login');
    }
  }, [router]);

  return (
    <div className="min-h-screen flex items-center justify-center">
      <div className="text-gray-600">Redirecting...</div>
    </div>
  );
}
```

### Step 11: Run Development Server (1 minute)

```bash
# Start development server
npm run dev
```

Open browser: **http://localhost:3000**

---

## ✅ Verification Checklist

Test the following:

1. **Login Page**
   - [ ] Visit http://localhost:3000
   - [ ] Should redirect to /login
   - [ ] Login form displays correctly
   - [ ] Can enter username/password
   - [ ] Click "Sign In"

2. **Authentication**
   - [ ] Login with valid credentials
   - [ ] Token stored in localStorage
   - [ ] Redirects to /dashboard
   - [ ] User info displayed

3. **Dashboard**
   - [ ] Dashboard loads
   - [ ] User name shows in header
   - [ ] Logout button visible
   - [ ] Click logout → redirects to login

4. **Protected Routes**
   - [ ] Logout, then visit /dashboard directly
   - [ ] Should redirect to /login

---

## 🎨 Current State vs Next.js

### Running Both Simultaneously

1. **HTML Version:** http://10.10.10.127:7000/index_v3.html
2. **Next.js Version:** http://localhost:3000

Both can run at the same time during migration!

### Port Configuration

```bash
# HTML version (existing)
Port 7000: Static file server

# Next.js version (new)
Port 3000: Development server
Port 3001: Production server (when we deploy)
```

---

## 📊 What We Have Now

After following this guide:

✅ Working Next.js project
✅ TypeScript configured
✅ Tailwind CSS setup
✅ Login page functional
✅ Dashboard skeleton
✅ API client ready
✅ Authentication working
✅ Logout functional
✅ Routing configured

---

## 🔥 Next Steps (After Quick Start)

### Phase 1: Enhance Login (1-2 days)
- [ ] Add loading spinner
- [ ] Improve error messages
- [ ] Add form validation
- [ ] Match HTML design exactly
- [ ] Add auto-redirect if logged in

### Phase 2: Build Dashboard Layout (2-3 days)
- [ ] Create sidebar component
- [ ] Add navigation menu
- [ ] Create header component
- [ ] Add user profile dropdown
- [ ] Implement search sections

### Phase 3: Transaction Search (3-4 days)
- [ ] Create search form component
- [ ] Add all search fields
- [ ] Implement API integration
- [ ] Add results table
- [ ] Pagination

### Phase 4: Document Viewer (2-3 days)
- [ ] PDF viewer modal
- [ ] Image gallery
- [ ] Document list
- [ ] Download functionality

---

## 🐛 Common Issues & Solutions

### Issue 1: "Module not found: Can't resolve '@/lib/api'"
**Solution:**
```bash
# Check tsconfig.json has:
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}
```

### Issue 2: "localStorage is not defined"
**Solution:** Use `typeof window !== 'undefined'` check
```typescript
if (typeof window !== 'undefined') {
  const token = localStorage.getItem('access_token');
}
```

### Issue 3: CORS errors
**Solution:** Use Next.js rewrites in `next.config.js` (already added above)

### Issue 4: Hydration errors
**Solution:** Use `'use client'` directive at top of component files

---

## 📞 Get Help

If stuck:
1. Check Next.js docs: https://nextjs.org/docs
2. Check console for errors (F12)
3. Review this guide step-by-step
4. Google the specific error message

---

## 🎯 Success!

If you can:
- ✅ Login with valid credentials
- ✅ See the dashboard
- ✅ Logout successfully
- ✅ Auto-redirect works

**You're ready to continue migration!** 🎉

---

**Time to Complete:** ~1 hour  
**Next:** Start migrating transaction search components  
**Status:** Ready for development

