diff --git a/frontend/app/(protected)/onboarding/page.tsx b/frontend/app/(protected)/onboarding/page.tsx new file mode 100644 index 0000000..c90f6a5 --- /dev/null +++ b/frontend/app/(protected)/onboarding/page.tsx @@ -0,0 +1,304 @@ +'use client'; + +import React, { useState, useEffect, useCallback } from 'react'; +import { useRouter } from 'next/navigation'; +import { + Sparkles, ShieldCheck, UploadCloud, AlertCircle, + CheckCircle2, Clock, FileText, ChevronRight, ChevronLeft +} from 'lucide-react'; + +const ONBOARDING_STORAGE_KEY = 'smalda:onboarding:completed'; + +export default function OnboardingPage() { + const router = useRouter(); + const [currentStep, setCurrentStep] = useState(1); + const [isUploading, setIsUploading] = useState(false); + const [uploadError, setUploadError] = useState(null); + const [dragActive, setDragActive] = useState(false); + + // 1. Check eligibility criteria: show only for accounts < 24h old with 0 documents + useEffect(() => { + const checkOnboardingEligibility = async () => { + const isCompleted = localStorage.getItem(ONBOARDING_STORAGE_KEY); + if (isCompleted === 'true') { + router.replace('/dashboard'); + return; + } + + try { + // Fetch current user details and document counts from your API services + const [userRes, docsRes] = await Promise.all([ + fetch('/api/user/profile'), + fetch('/api/documents') + ]); + + if (userRes.ok && docsRes.ok) { + const user = await userRes.json(); + const docs = await docsRes.json(); + + const accountCreatedTime = new Date(user.createdAt).getTime(); + const oneDayInMs = 24 * 60 * 60 * 1000; + const isNewAccount = (Date.now() - accountCreatedTime) < oneDayInMs; + const hasZeroDocs = docs.length === 0; + + // Bypass onboarding if they aren't a new user or already have historical assets + if (!isNewAccount || !hasZeroDocs) { + completeOnboarding(); + } + } + } catch (err) { + console.error('Failed to verify onboarding eligibility barriers:', err); + } + }; + + checkOnboardingEligibility(); + }, [router]); + + const completeOnboarding = useCallback(() => { + localStorage.setItem(ONBOARDING_STORAGE_KEY, 'true'); + router.push('/dashboard'); + }, [router]); + + // 2. Step 2 Drag and Drop Event Interceptors + const handleDrag = (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + if (e.type === "dragenter" || e.type === "dragover") { + setDragActive(true); + } else if (e.type === "dragleave") { + setDragActive(false); + } + }; + + const handleDrop = async (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setDragActive(false); + + if (e.dataTransfer.files && e.dataTransfer.files[0]) { + await uploadDocument(e.dataTransfer.files[0]); + } + }; + + const handleFileInput = async (e: React.ChangeEvent) => { + if (e.target.files && e.target.files[0]) { + await uploadDocument(e.target.files[0]); + } + }; + + // 3. API Upload Connection + const uploadDocument = async (file: File) => { + setIsUploading(true); + setUploadError(null); + + const formData = new FormData(); + formData.append('file', file); + + try { + const response = await fetch('/api/documents/upload', { + method: 'POST', + body: formData, + }); + + if (!response.ok) throw new Error('Upload transaction declined by endpoint.'); + + // Advance to next step once file is processed + setCurrentStep(3); + } catch (err: any) { + setUploadError(err.message || 'Something went wrong during ingestion.'); + } finally { + setIsUploading(false); + } + }; + + return ( +
+ {/* Upper Progress Banner Header */} +
+
+ + SMALDA Onboarding +
+ +
+ + {/* Main Multi-step Sliding Track Window */} +
+ + {/* STEP 1: WELCOME INFO */} + {currentStep === 1 && ( +
+

Welcome to SMALDA

+

+ SMALDA bridges the gap between documents and secure evaluation data metrics. Let's unpack the core underlying engine pipelines in plain language: +

+
+
+ +
+

Automated AI Risk Scoring

+

Our engine scans uploaded documents for validation anomalies, assigning contextual threat markers automatically.

+
+
+
+ +
+

Stellar Blockchain Verification

+

A unique cryptographic fingerprint of your file is anchored onto the Stellar ledger to lock proof-of-authenticity permanently.

+
+
+
+
+ )} + + {/* STEP 2: DRAG & DROP UPLOAD */} + {currentStep === 2 && ( +
+
+

Upload Your First File

+

Kickstart system tracking by submitting an analysis target document.

+
+ +
+ + + +

or drag and drop your file boundary box here

+ + {uploadError && ( +
+ + {uploadError} +
+ )} +
+
+ )} + + {/* STEP 3: STATUS MAP DEFINITIONS */} + {currentStep === 3 && ( +
+
+

Understanding Tracking Statuses

+

Here is how to monitor document evaluation files across their lifecycle pipelines:

+
+ +
+
+ +
+ PENDING + File is securely queued. +
+
+
+ +
+ ANALYZING + AI engines evaluating file parameters. +
+
+
+ +
+ VERIFIED + Cryptographic proof verified on Stellar. +
+
+
+ +
+ FLAGGED + Risk indicators exceeded threshold lines. +
+
+
+
+ )} + + {/* STEP 4: COMPLETE */} + {currentStep === 4 && ( +
+
+ +
+

Setup Complete!

+

+ Your tracking onboarding is finished. You are ready to open your analytics command matrix dashboard. +

+
+ )} +
+ + {/* Footer Controls & Navigation Step Gauges */} + +
+ ); +} \ No newline at end of file