feat: Implement website structure
- Add navigation with Themes, Puzzles, and Miscellany. - Create "coming soon" pages for Puzzles and Miscellany. - Create a Themes page with cards for various topics. - Implement basic boxy layout. - Prepare for future interactive additions and filtering. - Set up for Netlify deployment.
This commit is contained in:
parent
9debcb7e0b
commit
fb7bb4aca4
18 changed files with 682 additions and 42 deletions
55
src/components/ComingSoon.tsx
Normal file
55
src/components/ComingSoon.tsx
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import { Link } from "react-router-dom";
|
||||
import { ArrowLeft, Wrench } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
interface ComingSoonProps {
|
||||
title: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
const ComingSoon = ({ title, description }: ComingSoonProps) => {
|
||||
return (
|
||||
<div className="min-h-screen bg-background flex items-center justify-center px-4">
|
||||
<div className="text-center max-w-2xl mx-auto">
|
||||
<div className="w-24 h-24 bg-surface-variant rounded-full flex items-center justify-center mx-auto mb-8">
|
||||
<Wrench className="w-12 h-12 text-muted-foreground" />
|
||||
</div>
|
||||
|
||||
<h1 className="text-4xl font-bold text-foreground mb-4">
|
||||
{title}
|
||||
</h1>
|
||||
|
||||
<h2 className="text-2xl font-semibold text-accent mb-6">
|
||||
Coming Soon
|
||||
</h2>
|
||||
|
||||
<p className="text-muted-foreground text-lg leading-relaxed mb-8">
|
||||
{description ||
|
||||
"We're working hard to bring you amazing interactive educational content. This section will be filled with engaging puzzles, tools, and resources to enhance your learning experience."
|
||||
}
|
||||
</p>
|
||||
|
||||
<div className="bg-surface border border-outline rounded-lg p-6 mb-8">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Want to be notified when this section launches? We're building something special that will include:
|
||||
</p>
|
||||
<ul className="text-sm text-muted-foreground mt-3 space-y-1">
|
||||
<li>• Interactive learning modules</li>
|
||||
<li>• Real-time collaboration tools</li>
|
||||
<li>• Progress tracking and analytics</li>
|
||||
<li>• Customizable difficulty levels</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<Button asChild variant="outline">
|
||||
<Link to="/" className="inline-flex items-center">
|
||||
<ArrowLeft className="w-4 h-4 mr-2" />
|
||||
Back to Home
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ComingSoon;
|
||||
104
src/components/InteractiveCard.tsx
Normal file
104
src/components/InteractiveCard.tsx
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import { Badge } from "@/components/ui/badge";
|
||||
import { ArrowRight, Clock, Users } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface InteractiveCardProps {
|
||||
title: string;
|
||||
description: string;
|
||||
tags: string[];
|
||||
difficulty?: "Beginner" | "Intermediate" | "Advanced";
|
||||
duration?: string;
|
||||
participants?: string;
|
||||
imageUrl?: string;
|
||||
onClick?: () => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const InteractiveCard = ({
|
||||
title,
|
||||
description,
|
||||
tags,
|
||||
difficulty,
|
||||
duration,
|
||||
participants,
|
||||
imageUrl,
|
||||
onClick,
|
||||
className
|
||||
}: InteractiveCardProps) => {
|
||||
const difficultyColors = {
|
||||
Beginner: "bg-green-100 text-green-800",
|
||||
Intermediate: "bg-yellow-100 text-yellow-800",
|
||||
Advanced: "bg-red-100 text-red-800"
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={onClick}
|
||||
className={cn(
|
||||
"group cursor-pointer bg-surface border border-outline rounded-lg overflow-hidden shadow-card hover:shadow-card-hover transition-all duration-200 hover:-translate-y-1",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{imageUrl && (
|
||||
<div className="h-48 bg-surface-variant overflow-hidden">
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt={title}
|
||||
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="p-6">
|
||||
<div className="flex items-start justify-between mb-3">
|
||||
<h3 className="text-lg font-semibold text-foreground group-hover:text-accent transition-colors flex-1">
|
||||
{title}
|
||||
</h3>
|
||||
<ArrowRight className="w-5 h-5 text-muted-foreground group-hover:text-accent group-hover:translate-x-1 transition-all flex-shrink-0 ml-2" />
|
||||
</div>
|
||||
|
||||
<p className="text-muted-foreground text-sm leading-relaxed mb-4">
|
||||
{description}
|
||||
</p>
|
||||
|
||||
<div className="flex items-center gap-4 mb-4 text-xs text-muted-foreground">
|
||||
{duration && (
|
||||
<div className="flex items-center gap-1">
|
||||
<Clock className="w-3 h-3" />
|
||||
<span>{duration}</span>
|
||||
</div>
|
||||
)}
|
||||
{participants && (
|
||||
<div className="flex items-center gap-1">
|
||||
<Users className="w-3 h-3" />
|
||||
<span>{participants}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-2 mb-3">
|
||||
{difficulty && (
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className={cn("text-xs", difficultyColors[difficulty])}
|
||||
>
|
||||
{difficulty}
|
||||
</Badge>
|
||||
)}
|
||||
{tags.slice(0, 3).map((tag) => (
|
||||
<Badge key={tag} variant="outline" className="text-xs">
|
||||
{tag}
|
||||
</Badge>
|
||||
))}
|
||||
{tags.length > 3 && (
|
||||
<Badge variant="outline" className="text-xs">
|
||||
+{tags.length - 3}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default InteractiveCard;
|
||||
52
src/components/Navigation.tsx
Normal file
52
src/components/Navigation.tsx
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { Link, useLocation } from "react-router-dom";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Navigation = () => {
|
||||
const location = useLocation();
|
||||
|
||||
const navItems = [
|
||||
{ name: "Themes", path: "/themes" },
|
||||
{ name: "Puzzles", path: "/puzzles" },
|
||||
{ name: "Miscellany", path: "/miscellany" }
|
||||
];
|
||||
|
||||
return (
|
||||
<nav className="bg-surface border-b border-outline">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between h-16">
|
||||
<Link
|
||||
to="/"
|
||||
className="text-xl font-bold text-foreground hover:text-accent transition-colors"
|
||||
>
|
||||
EduInteractives
|
||||
</Link>
|
||||
|
||||
<div className="flex space-x-8">
|
||||
{navItems.map((item) => {
|
||||
const isActive = location.pathname === item.path;
|
||||
return (
|
||||
<Link
|
||||
key={item.name}
|
||||
to={item.path}
|
||||
className={cn(
|
||||
"px-3 py-2 text-sm font-medium transition-colors relative",
|
||||
isActive
|
||||
? "text-accent"
|
||||
: "text-foreground hover:text-accent"
|
||||
)}
|
||||
>
|
||||
{item.name}
|
||||
{isActive && (
|
||||
<div className="absolute bottom-0 left-0 right-0 h-0.5 bg-accent" />
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navigation;
|
||||
42
src/components/ThemeCard.tsx
Normal file
42
src/components/ThemeCard.tsx
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import { Link } from "react-router-dom";
|
||||
import { ArrowRight } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface ThemeCardProps {
|
||||
title: string;
|
||||
description: string;
|
||||
path: string;
|
||||
icon?: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const ThemeCard = ({ title, description, path, icon, className }: ThemeCardProps) => {
|
||||
return (
|
||||
<Link
|
||||
to={path}
|
||||
className={cn(
|
||||
"group block bg-surface border border-outline rounded-lg p-6 shadow-card hover:shadow-card-hover transition-all duration-200 hover:-translate-y-1",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex-1">
|
||||
{icon && (
|
||||
<div className="w-12 h-12 bg-surface-variant rounded-lg flex items-center justify-center mb-4 group-hover:bg-accent group-hover:text-accent-foreground transition-colors">
|
||||
{icon}
|
||||
</div>
|
||||
)}
|
||||
<h3 className="text-lg font-semibold text-foreground mb-2 group-hover:text-accent transition-colors">
|
||||
{title}
|
||||
</h3>
|
||||
<p className="text-muted-foreground text-sm leading-relaxed">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
<ArrowRight className="w-5 h-5 text-muted-foreground group-hover:text-accent group-hover:translate-x-1 transition-all flex-shrink-0 ml-4" />
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeCard;
|
||||
Loading…
Add table
Add a link
Reference in a new issue