Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
VITE_ENVIRONMENT="development|production"
VITE_SPACE_BASE_URL=base_url_of_the_space_server
VITE_FRONTEND_BASE_PATH=base_path_for_frontend
VITE_SPACE_ADMIN_API_KEY=your_space_api_key # Only work when using development environment
2 changes: 1 addition & 1 deletion frontend/src/components/contracts/ContractsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export default function ContractsTable({ contracts, page, setPage, limit, setLim
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
onClick={() => navigate(`/contracts/${c.userContact?.userId}`)}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}/contracts/${c.userContact?.userId}`)}
className="px-3 py-1 bg-indigo-600 hover:bg-indigo-700 text-white rounded-md text-sm transition-colors cursor-pointer"
>
View
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/layouts/logged-view/components/sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export default function Sidebar({
(selected === tab.path
? 'bg-indigo-100 dark:bg-gray-800 font-bold' : '')
}
onClick={() => navigate(tab.path)}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}${tab.path}`)}
aria-current={selected === tab.path ? 'page' : undefined}
>
{tab.icon}
Expand Down Expand Up @@ -155,7 +155,7 @@ export default function Sidebar({
(selected === tab.path
? 'bg-indigo-100 dark:bg-gray-800 font-bold' : '')
}
onClick={() => navigate(tab.path)}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}${tab.path}`)}
aria-current={selected === tab.path ? 'page' : undefined}
>
{tab.icon}
Expand All @@ -182,7 +182,7 @@ export default function Sidebar({
(selected === tab.path
? 'bg-indigo-100 dark:bg-gray-800 font-bold' : '')
}
onClick={() => navigate(tab.path)}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}${tab.path}`)}
aria-current={selected === tab.path ? 'page' : undefined}
>
{tab.icon}
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/pages/contracts/ContractDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export default function ContractDetailPage() {
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
onClick={() => navigate('/contracts/dashboard')}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}/contracts/dashboard`)}
className="inline-flex items-center px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white font-medium rounded-lg transition-colors cursor-pointer"
>
<svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
Expand All @@ -125,7 +125,7 @@ export default function ContractDetailPage() {
<motion.button
whileHover={{ scale: 1.1, x: -4 }}
whileTap={{ scale: 0.95 }}
onClick={() => navigate('/contracts/dashboard')}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}/contracts/dashboard`)}
className="p-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors cursor-pointer"
>
<svg className="w-6 h-6 text-gray-600 dark:text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
Expand Down Expand Up @@ -166,7 +166,7 @@ export default function ContractDetailPage() {
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
onClick={() => navigate('/contracts/dashboard')}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}/contracts/dashboard`)}
className="inline-flex items-center px-6 py-3 bg-indigo-600 hover:bg-indigo-700 text-white font-medium rounded-lg transition-colors shadow-lg hover:shadow-xl cursor-pointer"
>
<svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/login/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export default function LoginPage() {
<div className="text-center mt-4">
<button
type="button"
onClick={() => navigate('/register')}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}/register`)}
className="cursor-pointer text-indigo-600 dark:text-indigo-400 hover:text-indigo-800 dark:hover:text-indigo-300 text-sm font-medium transition-colors"
>
Don't have an account? Register here
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/not-found/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function NotFoundPage() {
</p>

<button
onClick={() => navigate('/')}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH ?? '/'}`)}
className="cursor-pointer inline-flex items-center gap-2 px-6 py-3 bg-indigo-600 hover:bg-indigo-700 text-white font-medium rounded-lg shadow-md transition-all hover:shadow-lg"
>
<FiHome size={20} />
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/pages/register/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default function RegisterPage() {
await registerUser({ username, password });
await login(username, password);
setSuccess(true);
navigate('/');
navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH ?? '/'}`);
} catch (error: any) {
setError(error.message || 'Registration failed. Please try again.');
}
Expand Down Expand Up @@ -129,7 +129,7 @@ export default function RegisterPage() {
<div className="text-center mt-4">
<button
type="button"
onClick={() => navigate('/')}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH ?? '/'}`)}
className="text-indigo-600 dark:text-indigo-400 hover:text-indigo-800 dark:hover:text-indigo-300 text-sm font-medium transition-colors"
>
Already have an account? Log in
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/services/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export default function ServicesPage() {
layout
whileHover={{ scale: 1.03, boxShadow: "0 4px 24px 0 rgba(99,102,241,0.10)" }}
whileTap={{ scale: 0.98 }}
onClick={() => navigate(`/services/${encodeURIComponent(service.name)}`)}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}/services/${encodeURIComponent(service.name)}`)}
className="flex items-center gap-4 w-full bg-white/80 dark:bg-gray-900 rounded-lg shadow border border-gray-200 dark:border-gray-800 px-6 py-5 transition cursor-pointer hover:bg-indigo-50 dark:hover:bg-gray-800 focus:outline-none"
>
<span className="bg-indigo-100 dark:bg-gray-800 text-indigo-600 dark:text-indigo-300 rounded-full p-2">
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/pages/welcome/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export default function WelcomePage() {
Recent Services
</h2>
<button
onClick={() => navigate('/services')}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}/services`)}
className="text-sm text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 dark:hover:text-indigo-300 flex items-center gap-1 cursor-pointer transition-colors"
>
View all <FiArrowRight />
Expand All @@ -177,7 +177,7 @@ export default function WelcomePage() {
<FiServer className="mx-auto mb-2" size={32} />
<p>No services yet</p>
<button
onClick={() => navigate('/services')}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}/services`)}
className="mt-3 text-sm text-indigo-600 dark:text-indigo-400 hover:underline cursor-pointer"
>
Create your first service
Expand All @@ -191,7 +191,7 @@ export default function WelcomePage() {
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: idx * 0.1 }}
onClick={() => navigate(`/services/${service.name}`)}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}/services/${service.name}`)}
className="cursor-pointer p-4 bg-gradient-to-r from-indigo-50 to-blue-50 dark:from-gray-700 dark:to-gray-600 rounded-lg hover:shadow-md transition-shadow border border-indigo-100 dark:border-gray-600"
>
<div className="flex items-center justify-between">
Expand All @@ -217,7 +217,7 @@ export default function WelcomePage() {
Recent Contracts
</h2>
<button
onClick={() => navigate('/contracts/dashboard')}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}/contracts/dashboard`)}
className="text-sm text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 flex items-center gap-1 cursor-pointer transition-colors"
>
View all <FiArrowRight />
Expand All @@ -234,7 +234,7 @@ export default function WelcomePage() {
<FiFileText className="mx-auto mb-2" size={32} />
<p>No contracts yet</p>
<button
onClick={() => navigate('/contracts/dashboard')}
onClick={() => navigate(`${import.meta.env.VITE_FRONTEND_BASE_PATH}/contracts/dashboard`)}
className="mt-3 text-sm text-blue-600 dark:text-blue-400 hover:underline cursor-pointer"
>
View contracts dashboard
Expand Down
28 changes: 14 additions & 14 deletions frontend/src/router/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function RequireAuth({ children }: { children: ReactNode }) {
const { isAuthenticated } = useAuth();
const location = useLocation();
if (!isAuthenticated) {
return <Navigate to="/" state={{ from: location }} replace />;
return <Navigate to={`${import.meta.env.VITE_FRONTEND_BASE_PATH ?? '/'}`} state={{ from: location }} replace />;
}
return <>{children}</>;
}
Expand All @@ -41,19 +41,19 @@ export function SpaceRouter() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<MainPage/>}/>
<Route path="/register" element={<RegisterPage/>}/>
<Route path="/contracts/dashboard" element={<RequireAuth><LoggedLayout><ContractsDashboard/></LoggedLayout></RequireAuth>} />
<Route path="/contracts/:userId" element={<RequireAuth><LoggedLayout><ContractDetailPage/></LoggedLayout></RequireAuth>} />
<Route path="/instance-monitoring" element={<RequireAuth><RequireRole allowedRoles={['ADMIN']}><LoggedLayout><InstanceMonitoringPage/></LoggedLayout></RequireRole></RequireAuth>} />
<Route path="/users" element={<RequireAuth><RequireRole allowedRoles={['ADMIN']}><LoggedLayout><UsersPage/></LoggedLayout></RequireRole></RequireAuth>} />
<Route path="/organizations" element={<RequireAuth><RequireRole allowedRoles={['ADMIN']}><LoggedLayout><OrganizationsPage/></LoggedLayout></RequireRole></RequireAuth>} />
<Route path="/members" element={<RequireAuth><LoggedLayout><MembersPage/></LoggedLayout></RequireAuth>}/>
<Route path="/api-keys" element={<RequireAuth><LoggedLayout><ApiKeysPage/></LoggedLayout></RequireAuth>}/>
<Route path="/services" element={<RequireAuth><LoggedLayout><ServicesPage/></LoggedLayout></RequireAuth>}/>
<Route path="/services/:name" element={<RequireAuth><LoggedLayout><ServiceDetailPage/></LoggedLayout></RequireAuth>}/>
<Route path="/settings" element={<RequireAuth><LoggedLayout><SettingsPage/></LoggedLayout></RequireAuth>}/>
<Route path="/organization-settings" element={<RequireAuth><LoggedLayout><OrganizationSettingsPage/></LoggedLayout></RequireAuth>}/>
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH ?? '/'} element={<MainPage/>}/>
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/register"} element={<RegisterPage/>}/>
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/contracts/dashboard"} element={<RequireAuth><LoggedLayout><ContractsDashboard/></LoggedLayout></RequireAuth>} />
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/contracts/:userId"} element={<RequireAuth><LoggedLayout><ContractDetailPage/></LoggedLayout></RequireAuth>} />
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/instance-monitoring"} element={<RequireAuth><RequireRole allowedRoles={['ADMIN']}><LoggedLayout><InstanceMonitoringPage/></LoggedLayout></RequireRole></RequireAuth>} />
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/users"} element={<RequireAuth><RequireRole allowedRoles={['ADMIN']}><LoggedLayout><UsersPage/></LoggedLayout></RequireRole></RequireAuth>} />
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/organizations"} element={<RequireAuth><RequireRole allowedRoles={['ADMIN']}><LoggedLayout><OrganizationsPage/></LoggedLayout></RequireRole></RequireAuth>} />
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/members"} element={<RequireAuth><LoggedLayout><MembersPage/></LoggedLayout></RequireAuth>}/>
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/api-keys"} element={<RequireAuth><LoggedLayout><ApiKeysPage/></LoggedLayout></RequireAuth>}/>
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/services"} element={<RequireAuth><LoggedLayout><ServicesPage/></LoggedLayout></RequireAuth>}/>
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/services/:name"} element={<RequireAuth><LoggedLayout><ServiceDetailPage/></LoggedLayout></RequireAuth>}/>
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/settings"} element={<RequireAuth><LoggedLayout><SettingsPage/></LoggedLayout></RequireAuth>}/>
<Route path={import.meta.env.VITE_FRONTEND_BASE_PATH + "/organization-settings"} element={<RequireAuth><LoggedLayout><OrganizationSettingsPage/></LoggedLayout></RequireAuth>}/>
<Route path="*" element={<NotFoundPage />} />
</Routes>
</BrowserRouter>
Expand Down
Loading