AnthoLume
diff --git a/frontend/src/pages/ProgressPage.tsx b/frontend/src/pages/ProgressPage.tsx
index 59b8cb7..4406976 100644
--- a/frontend/src/pages/ProgressPage.tsx
+++ b/frontend/src/pages/ProgressPage.tsx
@@ -1,16 +1,17 @@
import { Link } from 'react-router-dom';
import { useGetProgressList } from '../generated/anthoLumeAPIV1';
+import type { Progress } from '../generated/model';
import { Table } from '../components/Table';
export default function ProgressPage() {
const { data, isLoading } = useGetProgressList({ page: 1, limit: 15 });
- const progress = data?.data?.progress;
+ const progress = data?.status === 200 ? (data.data.progress ?? []) : [];
const columns = [
{
key: 'document_id' as const,
header: 'Document',
- render: (_: any, row: any) => (
+ render: (_value: Progress['document_id'], row: Progress) => (
value || 'Unknown',
+ render: (value: Progress['device_name']) => value || 'Unknown',
},
{
key: 'percentage' as const,
header: 'Percentage',
- render: (value: any) => (value ? `${Math.round(value)}%` : '0%'),
+ render: (value: Progress['percentage']) => (value ? `${Math.round(value)}%` : '0%'),
},
{
key: 'created_at' as const,
header: 'Created At',
- render: (value: any) => (value ? new Date(value).toLocaleDateString() : 'N/A'),
+ render: (value: Progress['created_at']) =>
+ value ? new Date(value).toLocaleDateString() : 'N/A',
},
];
diff --git a/frontend/src/pages/RegisterPage.tsx b/frontend/src/pages/RegisterPage.tsx
new file mode 100644
index 0000000..6f5f4ab
--- /dev/null
+++ b/frontend/src/pages/RegisterPage.tsx
@@ -0,0 +1,116 @@
+import { useState, FormEvent, useEffect } from 'react';
+import { Link, useNavigate } from 'react-router-dom';
+import { useAuth } from '../auth/AuthContext';
+import { Button } from '../components/Button';
+import { useToasts } from '../components/ToastContext';
+import { useGetInfo } from '../generated/anthoLumeAPIV1';
+
+export default function RegisterPage() {
+ const [username, setUsername] = useState('');
+ const [password, setPassword] = useState('');
+ const [isLoading, setIsLoading] = useState(false);
+
+ const { register, isAuthenticated, isCheckingAuth } = useAuth();
+ const navigate = useNavigate();
+ const { showError } = useToasts();
+ const { data: infoData, isLoading: isLoadingInfo } = useGetInfo({
+ query: {
+ staleTime: Infinity,
+ },
+ });
+
+ const registrationEnabled =
+ infoData && 'data' in infoData && infoData.data && 'registration_enabled' in infoData.data
+ ? infoData.data.registration_enabled
+ : false;
+
+ useEffect(() => {
+ if (!isCheckingAuth && isAuthenticated) {
+ navigate('/', { replace: true });
+ return;
+ }
+
+ if (!isLoadingInfo && !registrationEnabled) {
+ navigate('/login', { replace: true });
+ }
+ }, [isAuthenticated, isCheckingAuth, isLoadingInfo, navigate, registrationEnabled]);
+
+ const handleSubmit = async (e: FormEvent) => {
+ e.preventDefault();
+ setIsLoading(true);
+
+ try {
+ await register(username, password);
+ } catch (_err) {
+ showError(registrationEnabled ? 'Registration failed' : 'Registration is disabled');
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ return (
+
+ );
+}
diff --git a/frontend/src/pages/SearchPage.tsx b/frontend/src/pages/SearchPage.tsx
index 37472a3..f68f5e6 100644
--- a/frontend/src/pages/SearchPage.tsx
+++ b/frontend/src/pages/SearchPage.tsx
@@ -1,6 +1,7 @@
import { useState, FormEvent } from 'react';
import { useGetSearch } from '../generated/anthoLumeAPIV1';
import { GetSearchSource } from '../generated/model/getSearchSource';
+import type { SearchItem } from '../generated/model';
import { SearchIcon, DownloadIcon, BookIcon } from '../icons';
import { Button } from '../components/Button';
@@ -9,7 +10,7 @@ export default function SearchPage() {
const [source, setSource] = useState
(GetSearchSource.LibGen);
const { data, isLoading } = useGetSearch({ query, source });
- const results = data?.data?.results;
+ const results = data?.status === 200 ? data.data.results : [];
const handleSubmit = (e: FormEvent) => {
e.preventDefault();
@@ -97,7 +98,7 @@ export default function SearchPage() {
)}
{!isLoading &&
results &&
- results.map((item: any) => (
+ results.map((item: SearchItem) => (
|
|
- {!settingsData?.data.devices || settingsData.data.devices.length === 0 ? (
+ {!settingsData?.devices || settingsData.devices.length === 0 ? (
|
No Results
|
) : (
- settingsData.data.devices.map((device: any) => (
+ settingsData.devices.map((device: Device) => (
|
{device.device_name || 'Unknown'}
diff --git a/frontend/src/utils/errors.ts b/frontend/src/utils/errors.ts
new file mode 100644
index 0000000..4764bab
--- /dev/null
+++ b/frontend/src/utils/errors.ts
@@ -0,0 +1,27 @@
+export function getErrorMessage(error: unknown, fallback = 'Unknown error'): string {
+ if (error instanceof Error && error.message) {
+ return error.message;
+ }
+
+ if (typeof error === 'object' && error !== null) {
+ const errorWithResponse = error as {
+ message?: unknown;
+ response?: {
+ data?: {
+ message?: unknown;
+ };
+ };
+ };
+
+ const responseMessage = errorWithResponse.response?.data?.message;
+ if (typeof responseMessage === 'string' && responseMessage.trim() !== '') {
+ return responseMessage;
+ }
+
+ if (typeof errorWithResponse.message === 'string' && errorWithResponse.message.trim() !== '') {
+ return errorWithResponse.message;
+ }
+ }
+
+ return fallback;
+}
|