diff --git a/package-lock.json b/package-lock.json
index e90f663..07aa04b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,8 @@
"name": "italian-migrants-nt",
"version": "0.0.0",
"dependencies": {
+ "@radix-ui/react-avatar": "^1.1.9",
+ "@radix-ui/react-dialog": "^1.1.13",
"@radix-ui/react-label": "^2.1.6",
"@radix-ui/react-select": "^2.2.4",
"@radix-ui/react-slot": "^1.2.2",
@@ -1067,6 +1069,32 @@
}
}
},
+ "node_modules/@radix-ui/react-avatar": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.9.tgz",
+ "integrity": "sha512-10tQokfvZdFvnvDkcOJPjm2pWiP8A0R4T83MoD7tb15bC/k2GU7B1YBuzJi8lNQ8V1QqhP8ocNqp27ByZaNagQ==",
+ "dependencies": {
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.2",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-is-hydrated": "0.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-collection": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.6.tgz",
@@ -1120,6 +1148,41 @@
}
}
},
+ "node_modules/@radix-ui/react-dialog": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.13.tgz",
+ "integrity": "sha512-ARFmqUyhIVS3+riWzwGTe7JLjqwqgnODBUZdqpWar/z1WFs9z76fuOs/2BOWCR+YboRn4/WN9aoaGVwqNRr8VA==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.2",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.9",
+ "@radix-ui/react-focus-guards": "1.1.2",
+ "@radix-ui/react-focus-scope": "1.1.6",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-portal": "1.1.8",
+ "@radix-ui/react-presence": "1.1.4",
+ "@radix-ui/react-primitive": "2.1.2",
+ "@radix-ui/react-slot": "1.2.2",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-direction": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
@@ -1291,6 +1354,29 @@
}
}
},
+ "node_modules/@radix-ui/react-presence": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz",
+ "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-primitive": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.2.tgz",
@@ -1438,6 +1524,23 @@
}
}
},
+ "node_modules/@radix-ui/react-use-is-hydrated": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz",
+ "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==",
+ "dependencies": {
+ "use-sync-external-store": "^1.5.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-use-layout-effect": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
@@ -5232,6 +5335,14 @@
}
}
},
+ "node_modules/use-sync-external-store": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
+ "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
diff --git a/package.json b/package.json
index 9312c41..db6675f 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,8 @@
"preview": "vite preview"
},
"dependencies": {
+ "@radix-ui/react-avatar": "^1.1.9",
+ "@radix-ui/react-dialog": "^1.1.13",
"@radix-ui/react-label": "^2.1.6",
"@radix-ui/react-select": "^2.2.4",
"@radix-ui/react-slot": "^1.2.2",
diff --git a/public/hero.jpg b/public/hero.jpg
new file mode 100644
index 0000000..d345d3d
Binary files /dev/null and b/public/hero.jpg differ
diff --git a/src/App.css b/src/App.css
index e69de29..5a7873a 100644
--- a/src/App.css
+++ b/src/App.css
@@ -0,0 +1,2 @@
+@import "tailwindcss";
+@import "tw-animate-css";
diff --git a/src/components/HeroSection.tsx b/src/components/HeroSection.tsx
index 3059464..e39aa25 100644
--- a/src/components/HeroSection.tsx
+++ b/src/components/HeroSection.tsx
@@ -9,7 +9,7 @@ export default function HeroSection() {
@@ -32,7 +32,7 @@ export default function HeroSection() {
Italian Migration to the Northern Territory
-
+
Exploring the rich history and cultural legacy of Italian immigrants
in Australia's Northern Territory
diff --git a/src/components/HistoricalContext.tsx b/src/components/HistoricalContext.tsx
index f7cc7b4..c56fc6c 100644
--- a/src/components/HistoricalContext.tsx
+++ b/src/components/HistoricalContext.tsx
@@ -1,3 +1,5 @@
+import { Card, CardContent } from "./ui/card";
+
interface HistoricalContextProps {
year: number;
}
@@ -89,9 +91,12 @@ const HistoricalContext = ({ year }: HistoricalContextProps) => {
const context = getHistoricalContext(year);
return (
-
-
-
Historical Context
+
+
+
+ Contesto Storico
+
+
{context.period}
{context.description}
Key Events:
@@ -100,8 +105,8 @@ const HistoricalContext = ({ year }: HistoricalContextProps) => {
{event}
))}
-
-
+
+
);
};
diff --git a/src/components/MigrantProfileComponent.tsx b/src/components/MigrantProfileComponent.tsx
index e13669e..bbf08af 100644
--- a/src/components/MigrantProfileComponent.tsx
+++ b/src/components/MigrantProfileComponent.tsx
@@ -1,146 +1,228 @@
-import { Link } from "react-router-dom"
-import type { MigrantProfile } from "../types/migrant"
-import PhotoGallery from "./PhotoGallery"
-import RelatedMigrants from "./RelatedMigrants"
-import HistoricalContext from "./HistoricalContext"
+"use client";
-interface MigrantProfileComponentProps {
- migrant: MigrantProfile
+import { motion } from "framer-motion";
+import { Link } from "react-router-dom";
+import { ArrowLeft } from "lucide-react";
+import { Button } from "@/components/ui/button";
+import { Card, CardContent } from "@/components/ui/card";
+import PhotoGallery from "@/components/PhotoGallery";
+import RelatedMigrants from "@/components/RelatedMigrants";
+import HistoricalContext from "@/components/HistoricalContext";
+import AnimatedImage from "@/components/ui/animated-image";
+import type { MigrantProfile as MigrantProfileType } from "@/types/migrant";
+
+interface MigrantProfileProps {
+ migrant: MigrantProfileType;
}
-const MigrantProfileComponent = ({ migrant }: MigrantProfileComponentProps) => {
+export default function MigrantProfile({ migrant }: MigrantProfileProps) {
return (
{/* Hero section with main photo */}
-
-

+
-
-
-
+
+
+
+
{migrant.firstName} {migrant.lastName}
- {migrant.yearOfArrival} • {migrant.regionOfOrigin}, Italy → {migrant.settlementLocation}, NT
+ {migrant.yearOfArrival} • {migrant.regionOfOrigin}, Italy →{" "}
+ {migrant.settlementLocation}, NT
-
+
{/* Back button */}
-
-
- Back to Search
-
+
+
+
{/* Main content - 2/3 width on desktop */}
{/* Biographical information */}
-
-
-
Biographical Information
-
-
-
Full Name
-
- {migrant.firstName} {migrant.middleName ? migrant.middleName + " " : ""}
- {migrant.lastName}
-
+
+
+
+
+ Biographical Information
+
+
+
+
+
+ Full Name
+
+
+ {migrant.firstName}{" "}
+ {migrant.middleName ? migrant.middleName + " " : ""}
+ {migrant.lastName}
+
+
+
+
+ Birth Date
+
+
+ {migrant.birthDate || "Unknown"}
+
+
+
+
+ Birth Place
+
+
+ {migrant.birthPlace || "Unknown"}
+
+
+
+
+ Age at Migration
+
+
{migrant.ageAtMigration} years
+
+
+
+ Year of Arrival
+
+
{migrant.yearOfArrival}
+
+
+
+ Region of Origin
+
+
{migrant.regionOfOrigin}, Italy
+
+
+
+ Settlement Location
+
+
+ {migrant.settlementLocation}, NT
+
+
+
+
+ Occupation
+
+
+ {migrant.occupation || "Unknown"}
+
+
+ {migrant.deathDate && (
+ <>
+
+
+ Date of Death
+
+
{migrant.deathDate}
+
+
+
+ Place of Death
+
+
+ {migrant.deathPlace || "Unknown"}
+
+
+ >
+ )}
-
-
Birth Date
-
{migrant.birthDate || "Unknown"}
-
-
-
Birth Place
-
{migrant.birthPlace || "Unknown"}
-
-
-
Age at Migration
-
{migrant.ageAtMigration} years
-
-
-
Year of Arrival
-
{migrant.yearOfArrival}
-
-
-
Region of Origin
-
{migrant.regionOfOrigin}, Italy
-
-
-
Settlement Location
-
{migrant.settlementLocation}, NT
-
-
-
Occupation
-
{migrant.occupation || "Unknown"}
-
- {migrant.deathDate && (
- <>
-
-
Date of Death
-
{migrant.deathDate}
-
-
-
Place of Death
-
{migrant.deathPlace || "Unknown"}
-
- >
- )}
-
-
-
+
+
+
{/* Life story */}
{migrant.biography && (
-
-
-
Life Story
-
- {migrant.biography.split("\n").map((paragraph, index) => (
-
- {paragraph}
-
- ))}
-
-
-
+
+
+
+
+ La Storia di Vita
+
+
+
+ {migrant.biography.split("\n").map((paragraph, index) => (
+
+ {paragraph}
+
+ ))}
+
+
+
+
)}
{/* Photo gallery - only show if there are additional photos */}
- {migrant.photos && migrant.photos.length > 0 &&
}
+ {migrant.photos && migrant.photos.length > 0 && (
+
+
+
+ )}
{/* Sidebar - 1/3 width on desktop */}
{/* Historical context */}
-
+
+
+
{/* Related migrants */}
{migrant.relatedMigrants && migrant.relatedMigrants.length > 0 && (
-
+
+
+
)}
- )
+ );
}
-
-export default MigrantProfileComponent
diff --git a/src/components/PhotoGallery.tsx b/src/components/PhotoGallery.tsx
index 48009b1..0c5b29a 100644
--- a/src/components/PhotoGallery.tsx
+++ b/src/components/PhotoGallery.tsx
@@ -1,140 +1,132 @@
-"use client"
+"use client";
-import { useState } from "react"
-import type { Photo } from "../types/migrant"
+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[]
+ photos: Photo[];
}
-const PhotoGallery = ({ photos }: PhotoGalleryProps) => {
- const [currentPhotoIndex, setCurrentPhotoIndex] = useState
(null)
-
- const openModal = (index: number) => {
- setCurrentPhotoIndex(index)
- document.body.style.overflow = "hidden"
- }
-
- const closeModal = () => {
- setCurrentPhotoIndex(null)
- document.body.style.overflow = "auto"
- }
+export default function PhotoGallery({ photos }: PhotoGalleryProps) {
+ const [currentPhotoIndex, setCurrentPhotoIndex] = useState(0);
+ const [isDialogOpen, setIsDialogOpen] = useState(false);
const handlePrevious = () => {
- if (currentPhotoIndex === null) return
- setCurrentPhotoIndex((prev) => (prev === 0 ? photos.length - 1 : prev - 1))
- }
+ setCurrentPhotoIndex((prev) => (prev === 0 ? photos.length - 1 : prev - 1));
+ };
const handleNext = () => {
- if (currentPhotoIndex === null) return
- setCurrentPhotoIndex((prev) => (prev === photos.length - 1 ? 0 : prev + 1))
- }
+ setCurrentPhotoIndex((prev) => (prev === photos.length - 1 ? 0 : prev + 1));
+ };
return (
- <>
-
-
-
Photo Gallery
-
- {photos.map((photo, index) => (
-
- ))}
-
-
-
-
- {/* Modal */}
- {currentPhotoIndex !== null && (
-
-
-
- )}
- >
- )
+
+
+ );
}
-
-export default PhotoGallery
diff --git a/src/components/RelatedMigrants.tsx b/src/components/RelatedMigrants.tsx
index 59ef2b7..a8b8c46 100644
--- a/src/components/RelatedMigrants.tsx
+++ b/src/components/RelatedMigrants.tsx
@@ -1,41 +1,57 @@
-import { Link } from "react-router-dom"
-import type { RelatedMigrant } from "../types/migrant"
+import { Link } from "react-router-dom";
+import type { RelatedMigrant } from "../types/migrant";
+import { Card, CardContent } from "./ui/card";
+import { motion } from "framer-motion";
+import AnimatedImage from "./ui/animated-image";
interface RelatedMigrantsProps {
- migrants: RelatedMigrant[]
+ migrants: RelatedMigrant[];
}
const RelatedMigrants = ({ migrants }: RelatedMigrantsProps) => {
return (
-
-
-
Related Migrants
+
+
+
+ Migranti Correlati
+
+
- {migrants.map((migrant) => (
-
(
+
-
-

-
-
-
- {migrant.firstName} {migrant.lastName}
-
-
{migrant.relationship}
-
-
+
+
+
+
+ {migrant.firstName} {migrant.lastName}
+
+
+ {migrant.relationship}
+
+
+
+
))}
-
-
- )
-}
+
+
+ );
+};
-export default RelatedMigrants
+export default RelatedMigrants;
diff --git a/src/components/SearchForm.tsx b/src/components/SearchForm.tsx
index a0e5fbb..7301637 100644
--- a/src/components/SearchForm.tsx
+++ b/src/components/SearchForm.tsx
@@ -1,7 +1,9 @@
"use client";
import { useState, type ChangeEvent, type FormEvent } from "react";
-import type { SearchParams } from "../types/search";
+import type { SearchParams } from "@/types/search";
+import { Button } from "@/components/ui/button";
+import { Search } from "lucide-react";
// Mock data for autocomplete
const ITALIAN_REGIONS = [
@@ -192,19 +194,20 @@ const SearchForm = ({ onSearch }: SearchFormProps) => {
-
Reset
-
-
+
- Search Records
-
+ Search Records
+
);
diff --git a/src/components/SearchResults.tsx b/src/components/SearchResults.tsx
index c284911..5894206 100644
--- a/src/components/SearchResults.tsx
+++ b/src/components/SearchResults.tsx
@@ -1,67 +1,152 @@
-import { Link } from "react-router-dom"
-import type { SearchResult } from "../types/search"
-import LoadingSpinner from "./LoadingSpinner"
+"use client";
+
+import { Link } from "react-router-dom";
+import { motion, AnimatePresence } from "framer-motion";
+import type { SearchResult } from "@/types/search";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { Skeleton } from "@/components/ui/skeleton";
+import AnimatedImage from "@/components/ui/animated-image";
interface SearchResultsProps {
- results: SearchResult[]
- isLoading: boolean
+ results: SearchResult[];
+ isLoading: boolean;
+ hasSearched?: boolean;
}
-const SearchResults = ({ results, isLoading }: SearchResultsProps) => {
+export default function SearchResults({
+ results,
+ isLoading,
+ hasSearched = false,
+}: SearchResultsProps) {
+ const container = {
+ hidden: { opacity: 0 },
+ show: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.1,
+ },
+ },
+ };
+
+ const item = {
+ hidden: { opacity: 0, y: 20 },
+ show: { opacity: 1, y: 0, transition: { duration: 0.5 } },
+ };
+
if (isLoading) {
return (
-
-
-
Searching records...
+
+
+ Search Results
+
+
+ {[...Array(6)].map((_, i) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
- )
+ );
+ }
+
+ if (results.length === 0 && hasSearched) {
+ return (
+
+
+ No Results Found
+
+
+ Try adjusting your search criteria to find more records.
+
+
+ );
}
if (results.length === 0) {
- return (
-
-
No Results Found
-
Try adjusting your search criteria to find more records.
-
- )
+ return null;
}
return (
-
Search Results ({results.length})
-
- {results.map((person) => (
-
-
-
-

-
-
-
- {person.firstName} {person.lastName}
-
-
- Arrived {person.yearOfArrival} at age {person.ageAtMigration}
-
-
-
- From: {person.regionOfOrigin}, Italy
-
-
- Settled in: {person.settlementLocation}, NT
-
-
-
-
-
- ))}
-
+
+ Search Results ({results.length})
+
+
+
+ {results.map((person) => (
+
+
+
+
+
+
+ {person.firstName} {person.lastName}
+
+
+ Arrived {person.yearOfArrival} at age{" "}
+ {person.ageAtMigration}
+
+
+
+
+
+ From:{" "}
+ {person.regionOfOrigin}, Italy
+
+
+ Settled in:{" "}
+ {person.settlementLocation}, NT
+
+
+
+
+
+
+ ))}
+
+
- )
+ );
}
-
-export default SearchResults
diff --git a/src/components/SearchSection.tsx b/src/components/SearchSection.tsx
index 6c24fe1..c86a769 100644
--- a/src/components/SearchSection.tsx
+++ b/src/components/SearchSection.tsx
@@ -1,39 +1,43 @@
-"use client"
+"use client";
-import { useState } from "react"
-import SearchForm from "./SearchForm"
-import SearchResults from "./SearchResults"
-import type { SearchParams, SearchResult } from "../types/search"
-import { searchMigrants } from "../services/migrantService"
+import { useState } from "react";
+import SearchForm from "./SearchForm";
+import SearchResults from "./SearchResults";
+import type { SearchParams, SearchResult } from "../types/search";
+import { searchMigrants } from "../services/migrantService";
const SearchSection = () => {
- const [searchResults, setSearchResults] = useState
([])
- const [isSearching, setIsSearching] = useState(false)
- const [hasSearched, setHasSearched] = useState(false)
+ const [searchResults, setSearchResults] = useState([]);
+ const [isSearching, setIsSearching] = useState(false);
+ const [hasSearched, setHasSearched] = useState(false);
const handleSearch = async (params: SearchParams) => {
- setIsSearching(true)
+ setIsSearching(true);
try {
- const results = await searchMigrants(params)
- setSearchResults(results)
- setHasSearched(true)
+ const results = await searchMigrants(params);
+ setSearchResults(results);
+ setHasSearched(true);
} catch (error) {
- console.error("Error searching migrants:", error)
+ console.error("Error searching migrants:", error);
// In a real application, you would handle this error more gracefully
} finally {
- setIsSearching(false)
+ setIsSearching(false);
}
- }
+ };
return (
-
Search Historical Records
+
+ Search Historical Records
+
- {(isSearching || hasSearched) && }
+ {(isSearching || hasSearched) && (
+
+ )}
- )
-}
+ );
+};
-export default SearchSection
+export default SearchSection;
diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx
new file mode 100644
index 0000000..b7224f0
--- /dev/null
+++ b/src/components/ui/avatar.tsx
@@ -0,0 +1,51 @@
+import * as React from "react"
+import * as AvatarPrimitive from "@radix-ui/react-avatar"
+
+import { cn } from "@/lib/utils"
+
+function Avatar({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AvatarImage({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AvatarFallback({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export { Avatar, AvatarImage, AvatarFallback }
diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx
index 93a82d9..d28d5d5 100644
--- a/src/components/ui/card.tsx
+++ b/src/components/ui/card.tsx
@@ -75,7 +75,7 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
);
diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx
new file mode 100644
index 0000000..981e999
--- /dev/null
+++ b/src/components/ui/dialog.tsx
@@ -0,0 +1,133 @@
+import * as React from "react"
+import * as DialogPrimitive from "@radix-ui/react-dialog"
+import { XIcon } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+function Dialog({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogTrigger({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogPortal({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogClose({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogOverlay({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DialogContent({
+ className,
+ children,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ {children}
+
+
+ Close
+
+
+
+ )
+}
+
+function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function DialogTitle({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DialogDescription({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogOverlay,
+ DialogPortal,
+ DialogTitle,
+ DialogTrigger,
+}
diff --git a/src/components/ui/skeleton.tsx b/src/components/ui/skeleton.tsx
new file mode 100644
index 0000000..32ea0ef
--- /dev/null
+++ b/src/components/ui/skeleton.tsx
@@ -0,0 +1,13 @@
+import { cn } from "@/lib/utils"
+
+function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+export { Skeleton }
diff --git a/src/main.tsx b/src/main.tsx
index bef5202..10ed13e 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,10 +1,10 @@
-import { StrictMode } from 'react'
-import { createRoot } from 'react-dom/client'
-import './index.css'
-import App from './App.tsx'
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+import "./index.css";
+import App from "./App.tsx";
-createRoot(document.getElementById('root')!).render(
+createRoot(document.getElementById("root")!).render(
- ,
-)
+
+);
diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx
index 5661a34..508ab78 100644
--- a/src/pages/HomePage.tsx
+++ b/src/pages/HomePage.tsx
@@ -1,15 +1,15 @@
-import HeroSection from "../components/HeroSection"
-import IntroSection from "../components/IntroSection"
-import SearchSection from "../components/SearchSection"
+import HeroSection from "../components/HeroSection";
+import IntroSection from "../components/IntroSection";
+import SearchSection from "../components/SearchSection";
const HomePage = () => {
return (
-
+
- )
-}
+ );
+};
-export default HomePage
+export default HomePage;