diff --git a/build-local.sh b/build-local.sh new file mode 100644 index 0000000..55e0950 --- /dev/null +++ b/build-local.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +echo "Building application..." +npm run build + +echo "Deploying to Laravel public/assets folder..." +cp -r dist/* /home/mark/nun/public/assets + +echo "Deployment complete!" diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..842fb54 --- /dev/null +++ b/build.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -e + +echo "Building React app..." +npm run build + +echo "Copying React build files to Laravel public folder..." + +# Copy index.html to public root +cp dist/index.html /home/mark/nun/public/index.html + +# Copy assets folder contents to public/assets folder +cp -r dist/assets/* /home/mark/nun/public/assets/ + +echo "Deployment complete!" + + + + diff --git a/src/App.tsx b/src/App.tsx index 1b7b205..394e254 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,47 +1,144 @@ -import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; -// import { Toaster } from "react-hot-toast"; // ✅ Import Toaster +import { BrowserRouter as Router, Routes, Route, Navigate } from "react-router-dom"; +import { useState, useEffect, type ReactNode } from "react"; +import { Toaster } from "react-hot-toast"; +import "./App.css"; -// import MigrantProfilePage from "./pages/MigrantProfilePage"; -import NotFoundPage from "./pages/NotFoundPage"; -import LoginPage from "./components/admin/LoginPage"; -import Migrants from "./components/admin/Migrants"; -import ProfileSettings from "./components/ui/ProfileSettings"; -import AdminDashboardPage from "./components/admin/AdminDashboard"; +// Pages import HomePage from "./pages/HomePage"; +import NotFoundPage from "./pages/NotFoundPage"; +import MigrantProfilePage from "./pages/MigrantProfilePage"; + +// Admin Components +import LoginPage from "./components/admin/LoginPage"; import RegisterPage from "./components/admin/Register"; +import AdminDashboardPage from "./components/admin/AdminDashboard"; +import Migrants from "./components/admin/Migrants"; import AddMigrantPage from "./components/admin/AddMigrant"; -import SettingsPage from "./components/admin/Setting"; -import ReportsPage from "./components/admin/Reports"; import EditMigrant from "./components/admin/EditMigrant"; -import SearchResults from "./components/home/SearchResults"; -import Sample from "./components/admin/Table"; +import SettingsPage from "./components/admin/Setting"; +import ProfileSettings from "./components/ui/ProfileSettings"; +import ReportsPage from "./components/admin/Reports"; import UserCreate from "./components/admin/users/UserCreate"; -import { Toaster } from 'react-hot-toast';import "./App.css"; +import Sample from "./components/admin/Table"; + +// Charts import { MigrationChart } from "./components/charts/MigrationChart"; import { ResidenceChart } from "./components/charts/ResidenceChart"; -import MigrantProfilePage from "./pages/MigrantProfilePage"; + +// Other +import SearchResults from "./components/home/SearchResults"; +import apiService from "./services/apiService"; + +// Types +interface AuthContextType { + isAuthenticated: boolean; + isLoading: boolean; + user: any; +} + +interface ProtectedRouteProps { + children: ReactNode; +} + +// Protected Route +function ProtectedRoute({ children }: ProtectedRouteProps) { + const [authState, setAuthState] = useState({ + isAuthenticated: false, + isLoading: true, + user: null, + }); + + useEffect(() => { + const checkAuth = async () => { + try { + const token = localStorage.getItem("token"); + if (!token) return setAuthState({ isAuthenticated: false, isLoading: false, user: null }); + + const user = await apiService.fetchCurrentUser(); + setAuthState({ isAuthenticated: true, isLoading: false, user }); + } catch { + localStorage.removeItem("token"); + localStorage.removeItem("user"); + setAuthState({ isAuthenticated: false, isLoading: false, user: null }); + } + }; + checkAuth(); + }, []); + + if (authState.isLoading) { + return ( +
+
+
+

Verifying authentication...

+
+
+ ); + } + + return authState.isAuthenticated ? <>{children} : ; +} + +// Public Route +function PublicRoute({ children }: ProtectedRouteProps) { + const [isAuthenticated, setIsAuthenticated] = useState(null); + + useEffect(() => { + const checkAuthStatus = async () => { + try { + const token = localStorage.getItem("token"); + if (!token) return setIsAuthenticated(false); + + await apiService.fetchCurrentUser(); + setIsAuthenticated(true); + } catch { + localStorage.removeItem("token"); + localStorage.removeItem("user"); + setIsAuthenticated(false); + } + }; + checkAuthStatus(); + }, []); + + if (isAuthenticated === null) { + return ( +
+
+
+ ); + } + + return isAuthenticated ? : <>{children}; +} + function App() { return ( - {/* ✅ Add the Toaster at root level so it works everywhere */} - + - } /> + {/* Public Routes */} + } /> + } /> + } /> } /> } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + + {/* Auth Routes */} + } /> + } /> + + {/* Admin Protected Routes */} + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + {/* Catch All */} } /> diff --git a/src/components/admin/LoginPage.tsx b/src/components/admin/LoginPage.tsx index 51a2e93..1f72dd6 100644 --- a/src/components/admin/LoginPage.tsx +++ b/src/components/admin/LoginPage.tsx @@ -1,8 +1,6 @@ "use client" -import type React from "react" - -import { useState } from "react" +import React, { useState } from "react" import { useNavigate } from "react-router-dom" import { Eye, EyeOff, Lock, Mail } from "lucide-react" import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" @@ -20,22 +18,18 @@ export default function LoginPage() { const navigate = useNavigate() const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault() + e.preventDefault() // Prevent page reload setError("") setIsLoading(true) try { - const response = await apiService.login({ - email, - password, - }) - console.log("Response:", response.data) - alert("Login successful!") + const response = await apiService.login({ email, password }) + console.log("Response:", response) navigate("/admin") - } catch (error: any) { - console.error("Error submitting form:", error) - if (error.response && error.response.data && error.response.data.message) { - setError(error.response.data.message) + } catch (err: any) { + console.error("Login error:", err) + if (err.response?.data?.message) { + setError(err.response.data.message) } else { setError("Login failed. Please check your input and try again.") } @@ -65,9 +59,11 @@ export default function LoginPage() { value={email} onChange={(e) => setEmail(e.target.value)} required + autoComplete="username" /> +
@@ -79,18 +75,27 @@ export default function LoginPage() { value={password} onChange={(e) => setPassword(e.target.value)} required + autoComplete="current-password" />
- {error &&

{error}

} + + {/* Error message */} + {error && ( +
+ {error} +
+ )} + @@ -82,6 +120,40 @@ export default function UserCreate() {

Manage your profile and security preferences

+ {/* Current user information card */} + {user && ( +
+ +
+ + + + Current User Profile + + + +
+
+
+ {user.name.charAt(0).toUpperCase()} +
+
+
+
+

Full Name

+

{user.name}

+
+
+

Email Address

+

{user.email}

+
+
+
+
+
+
+ )} +
@@ -135,11 +207,14 @@ export default function UserCreate() { name="current_password" type="password" placeholder="Enter current password" + value={formData.current_password} + onChange={handleInputChange} required className="bg-gray-800 border-gray-700 text-white focus:border-[#9B2335] placeholder:text-gray-500" /> +
- +
- {/* Existing Photos */} {existingPhotos.length > 0 && (
-

Existing Photos

+

Existing Photos

{existingPhotos.length}
@@ -131,12 +130,11 @@ const PhotosStep: React.FC = ({
)} - {/* New Photos */} {photos.length > 0 && (
-

New Photos

+

New Photos

{photos.length}
diff --git a/src/components/home/HeroSection.tsx b/src/components/home/HeroSection.tsx index 428a4a2..d1b2b43 100644 --- a/src/components/home/HeroSection.tsx +++ b/src/components/home/HeroSection.tsx @@ -1,34 +1,46 @@ - - "use client" +import type React from "react" + import { Link } from "react-router-dom" -import { Search } from "lucide-react" +import { + Search, + Mail, + Phone, + MapPin, + Facebook, + Twitter, + Instagram, + Youtube, + Clock, + Users, + Database, + Award, +} from "lucide-react" import { Button } from "@/components/ui/button" import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel" import { Card, CardContent } from "@/components/ui/card" import SearchForm from "./SearchForm" import { useEffect, useState } from "react" import { useNavigate } from "react-router-dom" -import ApiService from "@/services/apiService"; -import type { Person } from "@/types/api"; +import ApiService from "@/services/apiService" +import type { Person } from "@/types/api" export default function Home() { const [currentSlide, setCurrentSlide] = useState(0) - const navigate = useNavigate(); - const [total, setTotal] = useState(0); - const [migrants, setMigrants] = useState([]); - const API_BASE_URL = "http://localhost:8000"; + const navigate = useNavigate() + const [total, setTotal] = useState(0) + const [migrants, setMigrants] = useState([]) + const API_BASE_URL = "http://localhost:8000" useEffect(() => { async function fetchData() { - const response = await ApiService.getMigrants(1, 10); - setMigrants(response.data); - setTotal(response.total); + const response = await ApiService.getMigrants(1, 10) + setMigrants(response.data) + setTotal(response.total) } - fetchData(); - }, []); - + fetchData() + }, []) const backgroundImages = [ { @@ -49,7 +61,6 @@ export default function Home() { }, ] - const galleryImages = [ { src: "https://images.unsplash.com/photo-1523906834658-6e24ef2386f9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80", @@ -80,6 +91,18 @@ export default function Home() { return () => clearInterval(timer) }, [backgroundImages.length]) + // Smooth scroll to contact section + const scrollToContact = (e: React.MouseEvent) => { + e.preventDefault() + const contactSection = document.getElementById("contact") + if (contactSection) { + contactSection.scrollIntoView({ + behavior: "smooth", + block: "start", + }) + } + } + return (
@@ -97,9 +120,13 @@ export default function Home() { Stories - + Contact - +
- ); + ) })} @@ -343,20 +370,211 @@ export default function Home() {
-
-
-

© {new Date().getFullYear()} Italian Migrants NT. All rights reserved.

- + + {/* Enhanced Footer with Contact Information */} +
+
+ {/* Main Footer Content */} +
+ {/* About Section */} +
+

Italian Migrants NT

+

+ Preserving and celebrating the rich heritage of Italian migrants to the Northern Territory through + digital archives, personal stories, and historical documentation. +

+
+ + Heritage Australia Recognition +
+
+ + {/* Contact Information */} +
+

Contact Us

+
+
+ +
+

Northern Territory Archives Centre

+

Kelsey Crescent, Millner NT 0810

+

Australia

+
+
+
+ + +61 8 8924 7677 +
+ +
+ +
+

Mon-Fri: 9:00 AM - 5:00 PM

+

Sat: 10:00 AM - 2:00 PM

+
+
+
+
+ + {/* Quick Links */} +
+

Quick Links

+ +
+ + {/* Resources & Social */} +
+

Resources

+ + +
+

Follow Us

+ +
+
+
+ + {/* Database Stats */} +
+
+
+
+ + {total.toLocaleString()} +
+

Total Records

+
+
+
+ + 2,847 +
+

Families Documented

+
+
+
+ + 156 +
+

Italian Regions

+
+
+
+ + 100+ +
+

Years of History

+
+
+
+ + {/* Bottom Footer */} +
+
+
+

© {new Date().getFullYear()} Italian Migrants NT. All rights reserved.

+
+ Powered by + Heritage Digital Archives +
+
+ +
+
diff --git a/src/components/home/MigrantProfileComponent.tsx b/src/components/home/MigrantProfileComponent.tsx index 1b2a640..0535cfd 100644 --- a/src/components/home/MigrantProfileComponent.tsx +++ b/src/components/home/MigrantProfileComponent.tsx @@ -47,21 +47,15 @@ export default function MigrantProfile() { Italian Migrants NT
diff --git a/src/components/home/PhotoGallery.tsx b/src/components/home/PhotoGallery.tsx deleted file mode 100644 index 0c5b29a..0000000 --- a/src/components/home/PhotoGallery.tsx +++ /dev/null @@ -1,132 +0,0 @@ -"use client"; - -import { useState } from "react"; -import { motion, AnimatePresence } from "framer-motion"; -import { Card, CardContent } from "@/components/ui/card"; -import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"; -import { ChevronLeft, ChevronRight, X } from "lucide-react"; -import { Button } from "@/components/ui/button"; -import AnimatedImage from "@/components/ui/animated-image"; -import type { Photo } from "@/types/migrant"; - -interface PhotoGalleryProps { - photos: Photo[]; -} - -export default function PhotoGallery({ photos }: PhotoGalleryProps) { - const [currentPhotoIndex, setCurrentPhotoIndex] = useState(0); - const [isDialogOpen, setIsDialogOpen] = useState(false); - - const handlePrevious = () => { - setCurrentPhotoIndex((prev) => (prev === 0 ? photos.length - 1 : prev - 1)); - }; - - const handleNext = () => { - setCurrentPhotoIndex((prev) => (prev === photos.length - 1 ? 0 : prev + 1)); - }; - - return ( - - -

- Galleria Fotografica -

-
-
- {photos.map((photo, index) => ( - - - setCurrentPhotoIndex(index)} - whileHover={{ scale: 1.03 }} - transition={{ duration: 0.2 }} - > - -
- {photo.caption && ( -
- {photo.caption} -
- )} - - - - - - -
- -
- {photos.length > 1 && ( - <> - - - - )} - {photos[currentPhotoIndex].caption && ( -
-

{photos[currentPhotoIndex].caption}

- {photos[currentPhotoIndex].year && ( -

- Year: {photos[currentPhotoIndex].year} -

- )} -
- )} -
-
-
-
- ))} -
- - - ); -} diff --git a/src/components/home/RelatedMigrants.tsx b/src/components/home/RelatedMigrants.tsx deleted file mode 100644 index 7cd3118..0000000 --- a/src/components/home/RelatedMigrants.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { Link } from "react-router-dom"; -import type { RelatedMigrant } from "@/types/migrant"; -import { Card, CardContent } from "@/components/ui/card"; -import { motion } from "framer-motion"; -import AnimatedImage from "@/components/ui/animated-image"; - -interface RelatedMigrantsProps { - migrants: RelatedMigrant[]; -} - -const RelatedMigrants = ({ migrants }: RelatedMigrantsProps) => { - return ( - - -

- Migranti Correlati -

-
-
- {migrants.map((migrant, index) => ( - - -
- -
-
-

- {migrant.firstName} {migrant.lastName} -

-

- {migrant.relationship} -

-
- -
- ))} -
- - - ); -}; - -export default RelatedMigrants; diff --git a/src/components/home/SearchResults.tsx b/src/components/home/SearchResults.tsx index e4d3fa3..946add3 100644 --- a/src/components/home/SearchResults.tsx +++ b/src/components/home/SearchResults.tsx @@ -4,7 +4,7 @@ import { } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { useMigrantsSearch } from "@/hooks/useMigrantsSearch"; - +import { formatDate } from "@/utils/date"; export default function SearchResults() { const { migrants, @@ -29,7 +29,7 @@ export default function SearchResults() { {["home", "about", "search", "stories", "contact"].map((path) => ( {path} @@ -87,18 +87,14 @@ export default function SearchResults() { -
- ID: - {migrant.person_id} -
Date of Birth: - {migrant.date_of_birth || "Unknown"} + {formatDate(migrant.date_of_birth) || "Unknown"}
{migrant.place_of_birth && (
Place of Birth: - {migrant.place_of_birth} + {formatDate(migrant.place_of_birth) || "Unknown"}
)}
diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx index ce1546f..b90c0b6 100644 --- a/src/components/layout/Sidebar.tsx +++ b/src/components/layout/Sidebar.tsx @@ -1,19 +1,33 @@ "use client" -import { useState } from "react" +import { useState, useEffect } from "react" import { BarChart3, Home, LogOut, Settings, Users, Menu, X, UserPlus, Shield } from "lucide-react" import { Link } from "react-router-dom" import { Button } from "@/components/ui/button" import { Separator } from "@/components/ui/separator" import apiService from "@/services/apiService" import LogoutDialog from "@/components/admin/migrant/Modal/LogoutDialog" +import type { User } from "@/types/api" export default function Sidebar() { - const [collapsed, setCollapsed] = useState(false) const [mobileOpen, setMobileOpen] = useState(false) const [logoutDialogOpen, setLogoutDialogOpen] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false) + const [user, setUser] = useState(null); + useEffect(() => { + async function loadUser() { + try { + const currentUser = await apiService.fetchCurrentUser(); + console.log("Fetched user:", currentUser); + setUser(currentUser); + } catch (error) { + console.error("Failed to fetch user info:", error); + } + } + loadUser(); + }, []) + const handleLogout = async () => { try { setIsSubmitting(true) @@ -65,8 +79,7 @@ export default function Sidebar() { {/* Sidebar */} ) -} +} \ No newline at end of file diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 384a46e..cfa84a3 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -4,37 +4,19 @@ import { XIcon } from "lucide-react" import { cn } from "@/lib/utils" -const Dialog = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->((props, ref) => { - return -}) -Dialog.displayName = "Dialog" +const Dialog = DialogPrimitive.Root +Dialog.displayName = DialogPrimitive.Root.displayName -const DialogTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->((props, ref) => { - return -}) -DialogTrigger.displayName = "DialogTrigger" +const DialogTrigger = DialogPrimitive.Trigger +DialogTrigger.displayName = DialogPrimitive.Trigger.displayName -const DialogPortal = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->((props, ref) => { - return -}) -DialogPortal.displayName = "DialogPortal" +const DialogPortal = ({ ...props }: DialogPrimitive.DialogPortalProps) => ( + +) +DialogPortal.displayName = DialogPrimitive.Portal.displayName -const DialogClose = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->((props, ref) => { - return -}) -DialogClose.displayName = "DialogClose" +const DialogClose = DialogPrimitive.Close +DialogClose.displayName = DialogPrimitive.Close.displayName const DialogOverlay = React.forwardRef< React.ElementRef, @@ -52,7 +34,7 @@ const DialogOverlay = React.forwardRef< /> ) }) -DialogOverlay.displayName = "DialogOverlay" +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName const DialogContent = React.forwardRef< React.ElementRef, @@ -71,7 +53,7 @@ const DialogContent = React.forwardRef< {...props} > {children} - + Close @@ -79,7 +61,7 @@ const DialogContent = React.forwardRef< ) }) -DialogContent.displayName = "DialogContent" +DialogContent.displayName = DialogPrimitive.Content.displayName const DialogHeader = React.forwardRef< HTMLDivElement, @@ -121,7 +103,7 @@ const DialogTitle = React.forwardRef< {...props} /> )) -DialogTitle.displayName = "DialogTitle" +DialogTitle.displayName = DialogPrimitive.Title.displayName const DialogDescription = React.forwardRef< React.ElementRef, @@ -134,7 +116,7 @@ const DialogDescription = React.forwardRef< {...props} /> )) -DialogDescription.displayName = "DialogDescription" +DialogDescription.displayName = DialogPrimitive.Description.displayName export { Dialog, diff --git a/src/components/ui/sonner.tsx b/src/components/ui/sonner.tsx index cd62aff..33d2d2a 100644 --- a/src/components/ui/sonner.tsx +++ b/src/components/ui/sonner.tsx @@ -1,5 +1,5 @@ import { useTheme } from "next-themes" -import { Toaster as Sonner, ToasterProps } from "sonner" +import { Toaster as Sonner, type ToasterProps } from "sonner" const Toaster = ({ ...props }: ToasterProps) => { const { theme = "system" } = useTheme() diff --git a/src/components/ui/toaster.tsx b/src/components/ui/toaster.tsx deleted file mode 100644 index 35f5a26..0000000 --- a/src/components/ui/toaster.tsx +++ /dev/null @@ -1,35 +0,0 @@ -"use client" - -import { - Toast, - ToastClose, - ToastDescription, - ToastProvider, - ToastTitle, - ToastViewport, -} from "@/components/ui/toast" -import { useToast } from "@/hooks/useToast" - -export function Toaster() { - const { toasts } = useToast() - - return ( - - {toasts.map(function ({ id, title, description, action, ...props }) { - return ( - -
- {title && {title}} - {description && ( - {description} - )} -
- {action} - -
- ) - })} - -
- ) -} diff --git a/src/hooks/useTabsPaneFormSubmit.ts b/src/hooks/useTabsPaneFormSubmit.ts index b0542c5..ce9b4d8 100644 --- a/src/hooks/useTabsPaneFormSubmit.ts +++ b/src/hooks/useTabsPaneFormSubmit.ts @@ -149,13 +149,9 @@ export const useTabsPaneFormSubmit = ({ Object.entries(family).forEach(([key, value]) => formData.append(`family[${key}]`, value)) Object.entries(internment).forEach(([key, value]) => formData.append(`internment[${key}]`, value)) - // Add new photos photos.forEach((file) => formData.append("photos[]", file)) - // Add all captions (existing + new) captions.forEach((caption, index) => formData.append(`captions[${index}]`, caption)) - - // Add main photo index and profile photo info if (mainPhotoIndex !== null) { formData.append("main_photo_index", mainPhotoIndex.toString()) formData.append("set_as_profile", "true") diff --git a/src/services/apiService.ts b/src/services/apiService.ts index efa05ca..c280f92 100644 --- a/src/services/apiService.ts +++ b/src/services/apiService.ts @@ -8,8 +8,9 @@ class ApiService { this.api = axios.create({ baseURL: import.meta.env.VITE_API_URL, headers: { "Content-Type": "application/json" }, + withCredentials: true, // IMPORTANT }); - + // Request Interceptor this.api.interceptors.request.use((config) => { const token = localStorage.getItem("token"); @@ -37,11 +38,13 @@ class ApiService { // --- AUTH --- async login(params: { email: string; password: string }) { return this.api.post("/api/login", params).then((res) => { + console.log("Token:", res.data.token); localStorage.setItem("token", res.data.token); localStorage.setItem("user", JSON.stringify(res.data.user)); return res.data; }); } + async register(params: { name: string; email: string; password: string }) { return this.api.post("/api/register", params).then((res) => res.data); @@ -50,7 +53,13 @@ class ApiService { async createUser(user: User) { return this.api.post("/api/register", user).then((res) => res.data); } - + async updateUser(user: User) { + return this.api.put("/api/user/account", user).then(res => res.data); + } + async displayAllUsers() { + return this.api.get("/api/users").then(res => res.data.data); + } + async logout() { return this.api.post("/api/logout").then((res) => { localStorage.removeItem("token"); @@ -58,6 +67,10 @@ class ApiService { return res.data; }); } + async fetchCurrentUser(): Promise { + return this.api.get("/api/user").then((res) => res.data.data.user); + } + // --- MIGRANTS --- async getMigrants(page = 1, perPage = 10, filters = {}): Promise { diff --git a/src/types/api.ts b/src/types/api.ts index 9afd1fc..5a32e7c 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -1,28 +1,30 @@ - export interface User { - name: string; - email: string; - password: string; - password_confirmation: string; - } - +export interface User { + name: string; + email: string; + password?: string; + current_password?: string; + password_confirmation?: string; +} export interface Migration { migration_id?: number; person_id?: number; - date_of_arrival_aus?: string; - date_of_arrival_nt?: string; - arrival_period?: string; - data_source?: string; + date_of_arrival_aus: string; + date_of_arrival_nt: string; + arrival_period: string; + data_source: string; created_at?: string; updated_at?: string; + + } export interface Naturalization { - naturalization_id?: number; - person_id?: number; - date_of_naturalisation?: string; - no_of_cert?: string; - issued_at?: string; + naturalization_id?: string; + person_id?: string; + date_of_naturalisation: string; + no_of_cert: string; + issued_at: string; created_at?: string; updated_at?: string; } @@ -30,8 +32,8 @@ export interface Naturalization { export interface Residence { residence_id?: number; person_id?: number; - town_or_city?: string; - home_at_death?: string; + town_or_city: string; + home_at_death: string; created_at?: string; updated_at?: string; } @@ -39,8 +41,8 @@ export interface Residence { export interface Family { family_id?: number; person_id?: number; - names_of_parents?: string; - names_of_children?: string; + names_of_parents: string; + names_of_children: string; created_at?: string; updated_at?: string; } @@ -48,12 +50,12 @@ export interface Family { export interface Internment { internment_id?: number; person_id?: number; - corps_issued?: string; - interned_in?: string; - sent_to?: string; - internee_occupation?: string; - internee_address?: string; - cav?: string; + corps_issued: string; + interned_in: string; + sent_to: string; + internee_occupation: string; + internee_address: string; + cav: string; created_at?: string; updated_at?: string; } @@ -75,17 +77,17 @@ export interface Photo { export interface Person { - person_id: number; - surname?: string; - christian_name?: string; + person_id?: number; + surname: string; + christian_name: string; full_name?: string; - date_of_birth?: string; - place_of_birth?: string; - date_of_death?: string; - occupation?: string; - additional_notes?: string; - reference?: string; - id_card_no?: string; + date_of_birth: string; + place_of_birth: string; + date_of_death: string; + occupation: string; + additional_notes: string; + reference: string; + id_card_no: string; created_at?: string; updated_at?: string; @@ -97,20 +99,12 @@ export interface Person { residence?: Residence | null; family?: Family | null; internment?: Internment | null; - data: Person[]; - total: number; + data?: Person[]; + total?: number; + last_page?: number; + current_page?: number; } - -export interface PaginatedResponse { - data: T[]; - current_page: number; - last_page: number; - total: number; - per_page: number; -} - - export interface createMigrantPayload { surname: string; christian_name: string; @@ -176,3 +170,12 @@ export interface ActivityLog { created_at: string; } +export interface ExistingPhoto { + id: number + caption?: string + is_profile_photo?: boolean + filename?: string + url?: string +} + +