2import { useState } from "react";
3import { apiClient } from "@/lib/client/apiClient";
5export default function LoginForm() {
6 const [username, setUsername] = useState("");
7 const [password, setPassword] = useState("");
8 const [storeName, setStoreName] = useState("");
9 const [loading, setLoading] = useState(false);
10 const [error, setError] = useState("");
12 async function handleLogin(e: React.FormEvent) {
18 // Validate store name
19 if (!storeName.trim()) {
20 setError("Please enter a store name");
25 // Demo mode for testing
26 const demoUsername = process.env.NEXT_PUBLIC_DEMO_USERNAME || "demo";
27 const isDemoMode = process.env.NEXT_PUBLIC_DEMO_MODE === "true";
29 if (isDemoMode && (username.toLowerCase() === demoUsername || username === "admin@iig.cwanz.online")) {
30 // Demo mode - redirect without server authentication
31 window.location.href = "/pages/home";
35 // Use secure server-side authentication with store name
36 console.log('[LoginForm] Attempting login:', { username, storeName, hasPassword: !!password });
37 const result = await apiClient.login(username, password, storeName.toLowerCase().trim());
39 console.log("Login result:", result);
42 // Redirect to specified page or default home
43 const redirectUrl = result.data?.redirect || "/pages/home";
44 console.log("Redirecting to:", redirectUrl);
45 window.location.href = redirectUrl;
47 setError(result.error || "Login failed");
50 console.error("Login error:", error);
51 setError("Unable to connect to server");
59 <form onSubmit={handleLogin} className="space-y-6">
60 {/* Store Name Input */}
62 <label htmlFor="storeName" className="block text-sm font-medium mb-2" style={{ color: '#1f2937' }}>
69 onChange={(e) => setStoreName(e.target.value)}
70 className="w-full px-3 py-2 rounded-md focus:outline-none focus:ring-2" style={{ border: '1px solid #d1d5db', background: 'white', color: '#1f2937', borderColor: '#d1d5db' }}
71 placeholder="e.g., iig, cowra, griffith, murwillumbah"
74 <p className="mt-1 text-xs" style={{ color: '#6b7280' }}>
75 Enter your store name (e.g., "iig" for management, "cowra" for Cowra store)
80 <label htmlFor="username" className="block text-sm font-medium mb-2" style={{ color: '#1f2937' }}>
87 onChange={(e) => setUsername(e.target.value)}
88 className="w-full px-3 py-2 rounded-md focus:outline-none focus:ring-2" style={{ border: '1px solid #d1d5db', background: 'white', color: '#1f2937' }}
89 placeholder="Enter your username"
95 <label htmlFor="password" className="block text-sm font-medium mb-2" style={{ color: '#1f2937' }}>
102 onChange={(e) => setPassword(e.target.value)}
103 className="w-full px-3 py-2 rounded-md focus:outline-none focus:ring-2" style={{ border: '1px solid #d1d5db', background: 'white', color: '#1f2937' }}
104 placeholder="Enter your password"
110 <div className="px-4 py-3 rounded-md" style={{ background: '#fee2e2', border: '1px solid #fca5a5' }}>
111 <span style={{ color: '#dc2626' }}>{error}</span>
118 className="w-full py-2 px-4 rounded-md hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
119 style={{ background: 'linear-gradient(to right, #2563eb, #7c3aed)', color: 'white' }}
121 {loading ? "Signing in..." : "Sign In"}
125 {process.env.NEXT_PUBLIC_DEMO_MODE === "true" && (
126 <div className="mt-6 p-4 rounded-md" style={{ background: '#dbeafe', border: '1px solid #93c5fd' }}>
127 <p className="text-sm" style={{ color: '#1e40af' }}>
128 <strong>Demo Mode:</strong> Use username "demo" with any password to access the demo.