make api base url configurable if not set

This commit is contained in:
Shroominic
2025-10-30 12:22:25 +08:00
parent 32253964dc
commit 968ebaf865
2 changed files with 95 additions and 10 deletions
+52 -6
View File
@@ -1,6 +1,7 @@
'use client';
import { useState, useEffect } from 'react';
import type { ChangeEvent, FormEvent } from 'react';
import { useRouter } from 'next/navigation';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
@@ -15,10 +16,12 @@ import { adminLogin } from '@/lib/api/services/auth';
import { ConfigurationService } from '@/lib/api/services/configuration';
import { toast } from 'sonner';
export default function AdminLoginPage() {
export default function AdminLoginPage(): JSX.Element {
const router = useRouter();
const [password, setPassword] = useState('');
const [isLoading, setIsLoading] = useState(false);
const allowCustomBaseUrl = !ConfigurationService.isEnvBaseUrlConfigured();
const [password, setPassword] = useState<string>('');
const [baseUrl, setBaseUrl] = useState<string>('');
const [isLoading, setIsLoading] = useState<boolean>(false);
useEffect(() => {
if (ConfigurationService.isTokenValid()) {
@@ -26,8 +29,35 @@ export default function AdminLoginPage() {
}
}, [router]);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
useEffect(() => {
if (!allowCustomBaseUrl) {
return;
}
const storedBaseUrl = ConfigurationService.getManualBaseUrl();
if (storedBaseUrl) {
setBaseUrl(storedBaseUrl);
return;
}
if (typeof window !== 'undefined') {
setBaseUrl(window.location.origin ?? '');
}
}, [allowCustomBaseUrl]);
const handleSubmit = async (
event: FormEvent<HTMLFormElement>
): Promise<void> => {
event.preventDefault();
if (allowCustomBaseUrl) {
const normalizedBaseUrl = baseUrl.trim();
if (!normalizedBaseUrl) {
toast.error('Please enter the API URL');
return;
}
ConfigurationService.setManualBaseUrl(normalizedBaseUrl);
}
if (!password) {
toast.error('Please enter your password');
@@ -60,12 +90,28 @@ export default function AdminLoginPage() {
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className='space-y-4'>
{allowCustomBaseUrl && (
<div className='space-y-2'>
<Input
type='text'
placeholder='API URL (https://api.example.com)'
value={baseUrl}
onChange={(event: ChangeEvent<HTMLInputElement>) =>
setBaseUrl(event.target.value)
}
disabled={isLoading}
required
/>
</div>
)}
<div className='space-y-2'>
<Input
type='password'
placeholder='Admin Password'
value={password}
onChange={(e) => setPassword(e.target.value)}
onChange={(event: ChangeEvent<HTMLInputElement>) =>
setPassword(event.target.value)
}
disabled={isLoading}
autoFocus
required
+43 -4
View File
@@ -15,6 +15,8 @@ export type ServerConfig = z.infer<typeof ServerConfigSchema>;
* Configuration service to manage external server settings
*/
export class ConfigurationService {
private static readonly manualBaseUrlStorageKey = 'admin_manual_base_url';
/**
* Get the current server configuration from localStorage
*/
@@ -59,11 +61,22 @@ export class ConfigurationService {
* Get the local base URL (never use external configuration)
*/
static getLocalBaseUrl(): string {
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
const envBaseUrl = process.env.NEXT_PUBLIC_API_URL;
console.log(apiUrl);
if (apiUrl) {
return apiUrl;
console.log(envBaseUrl);
if (envBaseUrl && envBaseUrl.trim()) {
return envBaseUrl;
}
if (typeof window !== 'undefined') {
const manualBaseUrl = this.getManualBaseUrl();
if (manualBaseUrl) {
return manualBaseUrl;
}
if (window.location.origin) {
return window.location.origin;
}
}
if (process.env.NODE_ENV === 'production') {
@@ -73,6 +86,32 @@ export class ConfigurationService {
return 'http://127.0.0.1:8000';
}
static isEnvBaseUrlConfigured(): boolean {
const envBaseUrl = process.env.NEXT_PUBLIC_API_URL ?? '';
return envBaseUrl.trim().length > 0;
}
static getManualBaseUrl(): string {
if (typeof window === 'undefined') {
return '';
}
return localStorage.getItem(this.manualBaseUrlStorageKey) ?? '';
}
static setManualBaseUrl(baseUrl: string): void {
if (typeof window === 'undefined') {
return;
}
const normalizedBaseUrl = baseUrl.trim();
if (normalizedBaseUrl) {
localStorage.setItem(this.manualBaseUrlStorageKey, normalizedBaseUrl);
} else {
localStorage.removeItem(this.manualBaseUrlStorageKey);
}
}
static isProduction(): boolean {
return process.env.NODE_ENV === 'production';
}