This commit is contained in:
Gökhan ÖZARSLAN 2026-08-16 16:34:19 +03:00
parent 7e222bacbf
commit 812f8dceec
4 changed files with 136 additions and 10 deletions

BIN
app.zip Normal file

Binary file not shown.

View File

@ -0,0 +1,61 @@
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
export default function AdminLogin() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const router = useRouter();
const handleLogin = (e: React.FormEvent) => {
e.preventDefault();
// Basic mock authentication
if (username && password) {
document.cookie = "auth_token=admin_token; path=/; max-age=3600";
router.push('/');
router.refresh();
}
};
return (
<div className="min-h-screen flex items-center justify-center bg-zinc-950 p-4">
<div className="w-full max-w-md bg-zinc-900 border border-zinc-800 rounded-2xl shadow-xl p-8">
<div className="text-center mb-8">
<h1 className="text-2xl font-light text-zinc-100 tracking-tight">ArmoReg <span className="font-semibold">Admin</span></h1>
<p className="text-zinc-500 text-sm mt-2">Sign in to central management</p>
</div>
<form onSubmit={handleLogin} className="space-y-5">
<div>
<label className="block text-sm font-medium text-zinc-400 mb-1">Username</label>
<input
type="text"
required
value={username}
onChange={(e) => setUsername(e.target.value)}
className="w-full bg-zinc-950 border border-zinc-800 rounded-lg px-4 py-2.5 text-zinc-100 focus:outline-none focus:border-zinc-600 focus:ring-1 focus:ring-zinc-600 transition-colors"
placeholder="admin"
/>
</div>
<div>
<label className="block text-sm font-medium text-zinc-400 mb-1">Password</label>
<input
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full bg-zinc-950 border border-zinc-800 rounded-lg px-4 py-2.5 text-zinc-100 focus:outline-none focus:border-zinc-600 focus:ring-1 focus:ring-zinc-600 transition-colors"
placeholder="••••••••"
/>
</div>
<button
type="submit"
className="w-full bg-white text-zinc-950 font-medium rounded-lg px-4 py-2.5 hover:bg-zinc-200 transition-colors mt-2"
>
Sign In
</button>
</form>
</div>
</div>
);
}

View File

@ -0,0 +1,61 @@
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
export default function TenantLogin() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const router = useRouter();
const handleLogin = (e: React.FormEvent) => {
e.preventDefault();
// Basic mock authentication
if (username && password) {
document.cookie = "auth_token=tenant_token; path=/; max-age=3600";
router.push('/');
router.refresh();
}
};
return (
<div className="min-h-screen flex items-center justify-center bg-zinc-50 p-4">
<div className="w-full max-w-md bg-white border border-zinc-200 rounded-2xl shadow-xl p-8">
<div className="text-center mb-8">
<h1 className="text-2xl font-light text-zinc-800 tracking-tight">Customer <span className="font-semibold text-blue-600">Panel</span></h1>
<p className="text-zinc-500 text-sm mt-2">Manage your Hotspot & Firewall</p>
</div>
<form onSubmit={handleLogin} className="space-y-5">
<div>
<label className="block text-sm font-medium text-zinc-600 mb-1">Tenant ID / Email</label>
<input
type="text"
required
value={username}
onChange={(e) => setUsername(e.target.value)}
className="w-full bg-white border border-zinc-300 rounded-lg px-4 py-2.5 text-zinc-900 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-colors"
placeholder="customer@domain.com"
/>
</div>
<div>
<label className="block text-sm font-medium text-zinc-600 mb-1">Password</label>
<input
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full bg-white border border-zinc-300 rounded-lg px-4 py-2.5 text-zinc-900 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-colors"
placeholder="••••••••"
/>
</div>
<button
type="submit"
className="w-full bg-blue-600 text-white font-medium rounded-lg px-4 py-2.5 hover:bg-blue-700 transition-colors mt-2 shadow-sm shadow-blue-200"
>
Sign In
</button>
</form>
</div>
</div>
);
}

View File

@ -3,27 +3,32 @@ import type { NextRequest } from 'next/server';
export const config = { export const config = {
matcher: [ matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico, sitemap.xml, robots.txt (metadata files)
*/
'/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)', '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',
], ],
}; };
export function middleware(req: NextRequest) { export function middleware(req: NextRequest) {
const url = req.nextUrl; const url = req.nextUrl;
// Get hostname (e.g., admin.armoreg.com, panel.armoreg.com, localhost:3000)
const hostname = req.headers.get('host') || ''; const hostname = req.headers.get('host') || '';
// Determine which subdomain we are on // Determine which subdomain we are on
const isAdmin = hostname.includes('admin.armoreg.com') || hostname.startsWith('admin.localhost'); const isAdmin = hostname.includes('admin.armoreg.com') || hostname.startsWith('admin.localhost');
const isPanel = hostname.includes('panel.armoreg.com') || hostname.startsWith('panel.localhost'); const isPanel = hostname.includes('panel.armoreg.com') || hostname.startsWith('panel.localhost');
// Simple authentication check via cookie (to be expanded later)
const isAuthenticated = req.cookies.has('auth_token');
const isLoginPage = url.pathname === '/login';
// If not authenticated and not on login page, redirect to login
if (!isAuthenticated && !isLoginPage) {
return NextResponse.redirect(new URL('/login', req.url));
}
// If authenticated and on login page, redirect to root
if (isAuthenticated && isLoginPage) {
return NextResponse.redirect(new URL('/', req.url));
}
// Rewrite to the appropriate folder inside /app // Rewrite to the appropriate folder inside /app
if (isAdmin) { if (isAdmin) {
return NextResponse.rewrite(new URL(`/admin${url.pathname}`, req.url)); return NextResponse.rewrite(new URL(`/admin${url.pathname}`, req.url));
@ -33,6 +38,5 @@ export function middleware(req: NextRequest) {
return NextResponse.rewrite(new URL(`/panel${url.pathname}`, req.url)); return NextResponse.rewrite(new URL(`/panel${url.pathname}`, req.url));
} }
// Default fallback (e.g. main landing page or redirect to panel)
return NextResponse.next(); return NextResponse.next();
} }