diff --git a/apps/web/app/(app)/loading/page.tsx b/apps/web/app/(app)/loading/page.tsx index 991f982..a20dee2 100644 --- a/apps/web/app/(app)/loading/page.tsx +++ b/apps/web/app/(app)/loading/page.tsx @@ -10,14 +10,9 @@ import { CardTitle, } from '@ultra-reporter/ui/components/card'; import { Progress } from '@ultra-reporter/ui/components/progress'; -import { getData } from '@ultra-reporter/ui/data'; -import { - convertToJson, - getTestResults, -} from '@ultra-reporter/utils/xml-parser'; import { Bug, MoveLeft } from 'lucide-react'; import { useRouter } from 'next/navigation'; -import { useEffect, useState } from 'react'; +import { JSX, useEffect, useState } from 'react'; const LoadingPage = (): JSX.Element => { const [progress, setProgress] = useState(0); @@ -25,29 +20,43 @@ const LoadingPage = (): JSX.Element => { const router = useRouter(); useEffect(() => { - const xmlContent = localStorage.getItem('xml-data'); - try { - setProgress(0); - if (!xmlContent) { - throw new Error('No XML data found in the file.'); - } - setProgress(25); - const jsonData = convertToJson(xmlContent); - setProgress(50); - const testResult = getTestResults(jsonData); - setProgress(75); - localStorage.setItem('json-data', JSON.stringify(getData(testResult))); - setProgress(100); - router.push('/results'); - } catch (err) { - if (err instanceof Error) { - setError(`${err.message}`); - if (process.env.VERCEL_ENV !== 'production') { - console.error(`Message: ${err.message} -Stack: ${err.stack}`); + const fetchData = async () => { + try { + setProgress(25); + + const response = await fetch('/api/format-data', { + body: JSON.stringify({ + value: localStorage.getItem('xml-data'), + }), + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + const errorData = await response.json(); + throw new Error(errorData.error || 'Failed to get formatted data'); + } + + setProgress(75); + const data = await response.json(); + + if (!data) { + throw new Error('No data received from server'); } + + localStorage.setItem('json-data', JSON.stringify(data)); + + setProgress(100); + router.push('/results'); + } catch (err) { + console.error('Error fetching data:', err); + setError(err instanceof Error ? err.message : 'Failed to load data'); } - } + }; + + fetchData(); }, [router]); const handleBack = (): void => { diff --git a/apps/web/app/(app)/page.tsx b/apps/web/app/(app)/page.tsx index 9a101b4..3782065 100644 --- a/apps/web/app/(app)/page.tsx +++ b/apps/web/app/(app)/page.tsx @@ -6,6 +6,7 @@ import { HowItWorks } from '@ultra-reporter/ui/home/how-it-works'; import { NavBar } from '@ultra-reporter/ui/home/nav-bar'; import { OpenSource } from '@ultra-reporter/ui/home/open-source'; import { Sponsor } from '@ultra-reporter/ui/home/sponsor'; +import { JSX } from 'react'; const LandingPage = (): JSX.Element => { return ( diff --git a/apps/web/app/(app)/results/page.tsx b/apps/web/app/(app)/results/page.tsx index 2833305..2c00c34 100644 --- a/apps/web/app/(app)/results/page.tsx +++ b/apps/web/app/(app)/results/page.tsx @@ -23,7 +23,7 @@ import { columns } from '@ultra-reporter/ui/data-table/table/columns'; import { NavBar } from '@ultra-reporter/ui/home/nav-bar'; import { cn } from '@ultra-reporter/utils/cn'; import { FormattedData } from '@ultra-reporter/utils/types'; -import { useEffect, useState } from 'react'; +import { JSX, useEffect, useState } from 'react'; const chartConfig: ChartConfig = { total: { @@ -63,13 +63,34 @@ const ResultsPage = (): JSX.Element => { const [isLoading, setIsLoading] = useState(true); useEffect(() => { - const resultData = localStorage.getItem('json-data') as string; - if (resultData) { - const testResult: TestResultData[] = JSON.parse(resultData); - setResult(testResult); - setFormattedData(getFormattedData(testResult)); - } - setIsLoading(false); + const loadData = async () => { + try { + const resultData = localStorage.getItem('json-data'); + if (resultData) { + const testResult: TestResultData[] = JSON.parse(resultData); + setResult(testResult); + setFormattedData(getFormattedData(testResult)); + setIsLoading(false); + return; + } + + // If no localStorage data, try to get from cookies + const response = await fetch('/api/get-formatted-data'); + if (response.ok) { + const data = await response.json(); + setResult(data); + setFormattedData(getFormattedData(data)); + // Save to localStorage for future use + localStorage.setItem('json-data', JSON.stringify(data)); + } + } catch (error) { + console.error('Error loading data:', error); + } finally { + setIsLoading(false); + } + }; + + loadData(); }, []); const { diff --git a/apps/web/app/api/format-data/route.ts b/apps/web/app/api/format-data/route.ts new file mode 100644 index 0000000..be895fa --- /dev/null +++ b/apps/web/app/api/format-data/route.ts @@ -0,0 +1,28 @@ +import { getData } from '@ultra-reporter/ui/data'; +import { getTestResults } from '@ultra-reporter/utils/xml-parser'; +import { NextRequest, NextResponse } from 'next/server'; + +export async function POST(request: NextRequest) { + try { + const { value } = await request.json(); + + if (!value) { + return NextResponse.json( + { error: 'Please upload a file first' }, + { status: 404 } + ); + } + + console.log(value); + const testResult = getTestResults(value); + const formattedData = getData(testResult); + + return NextResponse.json(formattedData); + } catch (error) { + console.error('Error getting formatted data:', error); + return NextResponse.json( + { error: 'Error retrieving formatted data' }, + { status: 500 } + ); + } +} diff --git a/apps/web/app/api/process-file/route.ts b/apps/web/app/api/process-file/route.ts new file mode 100644 index 0000000..123428a --- /dev/null +++ b/apps/web/app/api/process-file/route.ts @@ -0,0 +1,44 @@ +import { convertToJson } from '@ultra-reporter/utils/xml-parser'; +import { FileReader } from 'fs/promises'; +import { NextRequest, NextResponse } from 'next/server'; + +export async function POST(request: NextRequest) { + try { + const formData = await request.formData(); + const file = formData.get('file') as File; + + if (!file) { + return NextResponse.json({ error: 'No file provided' }, { status: 400 }); + } + + if (!file.name.endsWith('.xml')) { + return NextResponse.json( + { error: 'Invalid file type. Only XML files are allowed.' }, + { status: 400 } + ); + } + + let xmlContent: string | null = null; + const reader = new FileReader(); + reader.onload = async (e) => { + xmlContent = e.target?.result as string; + }; + reader.readAsText(file); + + if (!xmlContent) { + return NextResponse.json( + { error: 'Empty file content' }, + { status: 400 } + ); + } + + const jsonData = convertToJson(xmlContent); + return NextResponse.json(jsonData); + } catch (error) { + console.error('Error processing file:', error); + return NextResponse.json( + { error: 'Error processing file' }, + { status: 500 } + ); + } +} diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index 62a282a..d39b014 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -90,7 +90,7 @@ const RootLayout = async ({ {children}