Remove Dev-Link pages and redirect to Nexus opportunities

Removes all pages and components related to Dev-Link, updating routes in App.tsx to redirect /dev-link and /dev-link/waitlist to /opportunities?ecosystem=roblox.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9203795e-937a-4306-b81d-b4d5c78c240e
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: a73e905c-11b2-4d95-8ad7-db01d93e9347
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7c94b7a0-29c7-4f2e-94ef-44b2153872b7/9203795e-937a-4306-b81d-b4d5c78c240e/aPpJgbb
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
sirpiglr 2025-12-13 02:25:57 +00:00
parent 2ff1292bf6
commit ee1e052094
9 changed files with 5 additions and 1732 deletions

View file

@ -27,8 +27,6 @@ import GameForge from "./pages/GameForge";
import Foundation from "./pages/Foundation";
import Corp from "./pages/Corp";
import Staff from "./pages/Staff";
import DevLink from "./pages/DevLink";
import DevLinkProfiles from "./pages/DevLinkProfiles";
import Nexus from "./pages/Nexus";
import Arms from "./pages/Arms";
import ExternalRedirect from "./components/ExternalRedirect";
@ -94,7 +92,6 @@ import Investors from "./pages/Investors";
import NexusDashboard from "./pages/dashboards/NexusDashboard";
import LabsDashboard from "./pages/dashboards/LabsDashboard";
import GameForgeDashboard from "./pages/dashboards/GameForgeDashboard";
import DevLinkDashboard from "./pages/dashboards/DevLinkDashboard";
import StaffDashboard from "./pages/dashboards/StaffDashboard";
import Roadmap from "./pages/Roadmap";
import Trust from "./pages/Trust";
@ -211,9 +208,10 @@ const App = () => (
path="/dashboard/gameforge"
element={<ExternalRedirect to="https://aethex.foundation/gameforge/dashboard" />}
/>
{/* Dev-Link dashboard redirects to Nexus dashboard */}
<Route
path="/dashboard/dev-link"
element={<DevLinkDashboard />}
element={<Navigate to="/dashboard/nexus" replace />}
/>
<Route
path="/hub/client"
@ -502,11 +500,11 @@ const App = () => (
}
/>
{/* Dev-Link routes */}
<Route path="/dev-link" element={<DevLink />} />
{/* Dev-Link routes - now redirect to Nexus Opportunities with ecosystem filter */}
<Route path="/dev-link" element={<Navigate to="/opportunities?ecosystem=roblox" replace />} />
<Route
path="/dev-link/waitlist"
element={<DevLinkProfiles />}
element={<Navigate to="/opportunities?ecosystem=roblox" replace />}
/>
{/* Client Hub routes */}

View file

@ -1,198 +0,0 @@
import Layout from "@/components/Layout";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Users, Briefcase, Star, Zap } from "lucide-react";
import { useNavigate } from "react-router-dom";
import { useEffect, useState, useRef } from "react";
import LoadingScreen from "@/components/LoadingScreen";
import { useArmToast } from "@/hooks/use-arm-toast";
export default function DevLink() {
const navigate = useNavigate();
const armToast = useArmToast();
const [isLoading, setIsLoading] = useState(true);
const toastShownRef = useRef(false);
useEffect(() => {
const timer = setTimeout(() => {
setIsLoading(false);
if (!toastShownRef.current) {
armToast.system("Dev-Link platform loaded");
toastShownRef.current = true;
}
}, 900);
return () => clearTimeout(timer);
}, [armToast]);
if (isLoading) {
return (
<LoadingScreen
message="Loading Dev-Link Platform..."
showProgress={true}
duration={900}
accentColor="from-cyan-500 to-cyan-400"
armLogo="https://cdn.builder.io/api/v1/image/assets%2Ffc53d607e21d497595ac97e0637001a1%2F9a96b43cbd7b49bb9d5434580319c793?format=webp&width=800"
/>
);
}
return (
<Layout>
<div className="relative min-h-screen bg-black text-white overflow-hidden">
{/* Animated backgrounds */}
<div className="pointer-events-none absolute inset-0 opacity-[0.12] [background-image:radial-gradient(circle_at_top,#06b6d4_0,rgba(0,0,0,0.45)_55%,rgba(0,0,0,0.9)_100%)]" />
<div className="pointer-events-none absolute inset-0 bg-[linear-gradient(transparent_0,transparent_calc(100%-1px),rgba(6,182,212,0.05)_calc(100%-1px))] bg-[length:100%_32px]" />
<div className="pointer-events-none absolute inset-0 opacity-[0.08] [background-image:linear-gradient(90deg,rgba(6,182,212,0.1)_1px,transparent_1px),linear-gradient(0deg,rgba(6,182,212,0.1)_1px,transparent_1px)] [background-size:50px_50px] animate-pulse" />
<div className="pointer-events-none absolute top-20 left-10 w-72 h-72 bg-cyan-500/20 rounded-full blur-3xl animate-blob" />
<div className="pointer-events-none absolute bottom-20 right-10 w-72 h-72 bg-cyan-600/10 rounded-full blur-3xl animate-blob" />
<main className="relative z-10">
{/* Hero Section */}
<section className="relative overflow-hidden py-20 lg:py-28">
<div className="container mx-auto max-w-6xl px-4 text-center">
<div className="mx-auto flex max-w-3xl flex-col items-center gap-8">
<Badge
variant="outline"
className="border-cyan-400/40 bg-cyan-500/10 text-cyan-300 shadow-[0_0_20px_rgba(6,182,212,0.2)]"
>
<img
src="https://cdn.builder.io/api/v1/image/assets%2Ffc53d607e21d497595ac97e0637001a1%2F9a96b43cbd7b49bb9d5434580319c793?format=webp&width=800"
alt="Dev-Link"
className="h-5 w-5 mr-2"
/>
Dev-Link
</Badge>
<h1 className="text-4xl font-black tracking-tight text-cyan-300 sm:text-5xl lg:text-6xl">
LinkedIn for Roblox
</h1>
<p className="text-lg text-cyan-100/90 sm:text-xl">
Connect with Roblox developers, showcase your portfolio, find
collaborators, and land your next opportunity. The
professional network built by Roblox creators, for Roblox
creators.
</p>
<Button
size="lg"
className="bg-cyan-400 text-black shadow-[0_0_30px_rgba(6,182,212,0.35)] transition hover:bg-cyan-300"
onClick={() => navigate("/dev-link/waitlist")}
>
<Users className="mr-2 h-5 w-5" />
Join Waitlist
</Button>
</div>
</div>
</section>
{/* Features Grid */}
<section className="border-y border-cyan-400/10 bg-black/80 py-16">
<div className="container mx-auto max-w-6xl px-4">
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
<Card className="bg-cyan-950/20 border-cyan-400/30 hover:border-cyan-400/60 transition-colors">
<CardHeader>
<Users className="h-8 w-8 text-cyan-400 mb-2" />
<CardTitle className="text-cyan-300">Network</CardTitle>
</CardHeader>
<CardContent>
<p className="text-sm text-cyan-200/70">
Connect with thousands of Roblox developers worldwide and
expand your opportunities.
</p>
</CardContent>
</Card>
<Card className="bg-cyan-950/20 border-cyan-400/30 hover:border-cyan-400/60 transition-colors">
<CardHeader>
<Briefcase className="h-8 w-8 text-cyan-400 mb-2" />
<CardTitle className="text-cyan-300">
Opportunities
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-sm text-cyan-200/70">
Discover jobs, collaborations, and projects tailored to
your skills and interests.
</p>
</CardContent>
</Card>
<Card className="bg-cyan-950/20 border-cyan-400/30 hover:border-cyan-400/60 transition-colors">
<CardHeader>
<Star className="h-8 w-8 text-cyan-400 mb-2" />
<CardTitle className="text-cyan-300">Portfolio</CardTitle>
</CardHeader>
<CardContent>
<p className="text-sm text-cyan-200/70">
Showcase your best work and build your professional
reputation in the community.
</p>
</CardContent>
</Card>
<Card className="bg-cyan-950/20 border-cyan-400/30 hover:border-cyan-400/60 transition-colors">
<CardHeader>
<Zap className="h-8 w-8 text-cyan-400 mb-2" />
<CardTitle className="text-cyan-300">Collaborate</CardTitle>
</CardHeader>
<CardContent>
<p className="text-sm text-cyan-200/70">
Team up with other creators to build amazing games and
experiences together.
</p>
</CardContent>
</Card>
</div>
</div>
</section>
{/* CTA Section */}
<section className="py-20 lg:py-28">
<div className="container mx-auto max-w-4xl px-4 text-center">
<h2 className="text-4xl font-bold text-cyan-300 mb-4">
Your Roblox Career Starts Here
</h2>
<p className="text-lg text-cyan-100/80 mb-8">
Join the professional community for Roblox developers. Connect,
showcase, and grow.
</p>
<Button
size="lg"
className="bg-cyan-400 text-black shadow-[0_0_30px_rgba(6,182,212,0.35)] hover:bg-cyan-300"
>
Start Your Profile
</Button>
{/* Creator Network CTAs */}
<div className="mt-8 pt-8 border-t border-cyan-400/20">
<p className="text-sm text-cyan-200/70 mb-4">
Explore our creator community:
</p>
<div className="flex flex-col sm:flex-row gap-3 justify-center">
<Button
size="sm"
variant="outline"
className="border-cyan-400/30 text-cyan-300 hover:bg-cyan-500/10"
onClick={() => navigate("/creators")}
>
Browse All Creators
</Button>
<Button
size="sm"
variant="outline"
className="border-cyan-400/30 text-cyan-300 hover:bg-cyan-500/10"
onClick={() => navigate("/opportunities")}
>
View All Opportunities
</Button>
</div>
</div>
</div>
</section>
</main>
</div>
</Layout>
);
}

View file

@ -1,324 +0,0 @@
import Layout from "@/components/Layout";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { useParams, useNavigate } from "react-router-dom";
import { useEffect, useState } from "react";
import {
Github,
Globe,
Mail,
ArrowLeft,
ExternalLink,
MessageSquare,
Share2,
MapPin,
Trophy,
Briefcase,
} from "lucide-react";
import { supabase } from "@/lib/supabase";
interface DevProfile {
id: string;
user_id: string;
full_name: string;
avatar_url?: string;
bio?: string;
skills: string[];
experience_level: "beginner" | "intermediate" | "advanced" | "expert";
looking_for?: string;
portfolio_url?: string;
github_url?: string;
email?: string;
city?: string;
country?: string;
created_at: string;
}
export default function DevLinkProfile() {
const { profileId } = useParams<{ profileId: string }>();
const navigate = useNavigate();
const [profile, setProfile] = useState<DevProfile | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchProfile = async () => {
if (!profileId) {
setError("Profile not found");
setLoading(false);
return;
}
try {
const { data, error: fetchError } = await supabase
.from("profiles")
.select("*")
.eq("id", profileId)
.single();
if (fetchError) throw fetchError;
const devProfile: DevProfile = {
id: data.id,
user_id: data.user_id,
full_name: data.full_name || "Anonymous Developer",
avatar_url: data.avatar_url,
bio: data.bio,
skills: data.interests || [],
experience_level: data.experience_level || "intermediate",
looking_for: data.looking_for,
portfolio_url: data.portfolio_url,
github_url: data.github_url,
email: data.email,
city: data.city,
country: data.country,
created_at: data.created_at,
};
setProfile(devProfile);
} catch (err) {
console.error("Error fetching profile:", err);
setError("Failed to load profile");
} finally {
setLoading(false);
}
};
fetchProfile();
}, [profileId]);
const getExperienceColor = (level: string) => {
const colors: Record<string, string> = {
beginner: "bg-blue-500/20 text-blue-300 border-blue-400/40",
intermediate: "bg-cyan-500/20 text-cyan-300 border-cyan-400/40",
advanced: "bg-violet-500/20 text-violet-300 border-violet-400/40",
expert: "bg-amber-500/20 text-amber-300 border-amber-400/40",
};
return colors[level] || colors.intermediate;
};
if (loading) {
return (
<Layout>
<div className="relative min-h-screen bg-black text-white overflow-hidden flex items-center justify-center">
<div className="pointer-events-none absolute inset-0 opacity-[0.12] [background-image:radial-gradient(circle_at_top,#06b6d4_0,rgba(0,0,0,0.45)_55%,rgba(0,0,0,0.9)_100%)]" />
<p className="relative z-10 text-cyan-200/60">Loading profile...</p>
</div>
</Layout>
);
}
if (error || !profile) {
return (
<Layout>
<div className="relative min-h-screen bg-black text-white overflow-hidden flex items-center justify-center">
<div className="pointer-events-none absolute inset-0 opacity-[0.12] [background-image:radial-gradient(circle_at_top,#06b6d4_0,rgba(0,0,0,0.45)_55%,rgba(0,0,0,0.9)_100%)]" />
<div className="relative z-10 text-center">
<p className="text-cyan-200/60 text-lg mb-4">
{error || "Profile not found"}
</p>
<Button
onClick={() => navigate("/dev-link/profiles")}
className="bg-cyan-400 text-black hover:bg-cyan-300"
>
Back to Profiles
</Button>
</div>
</div>
</Layout>
);
}
return (
<Layout>
<div className="relative min-h-screen bg-black text-white overflow-hidden">
{/* Animated backgrounds */}
<div className="pointer-events-none absolute inset-0 opacity-[0.12] [background-image:radial-gradient(circle_at_top,#06b6d4_0,rgba(0,0,0,0.45)_55%,rgba(0,0,0,0.9)_100%)]" />
<div className="pointer-events-none absolute inset-0 bg-[linear-gradient(transparent_0,transparent_calc(100%-1px),rgba(6,182,212,0.05)_calc(100%-1px))] bg-[length:100%_32px]" />
<div className="pointer-events-none absolute inset-0 opacity-[0.08] [background-image:linear-gradient(90deg,rgba(6,182,212,0.1)_1px,transparent_1px),linear-gradient(0deg,rgba(6,182,212,0.1)_1px,transparent_1px)] [background-size:50px_50px] animate-pulse" />
<div className="pointer-events-none absolute top-20 left-10 w-72 h-72 bg-cyan-500/20 rounded-full blur-3xl animate-blob" />
<div className="pointer-events-none absolute bottom-20 right-10 w-72 h-72 bg-cyan-600/10 rounded-full blur-3xl animate-blob" />
<main className="relative z-10">
{/* Header */}
<section className="relative overflow-hidden py-8 lg:py-12">
<div className="container mx-auto max-w-4xl px-4">
<div className="flex items-center gap-3 mb-8">
<img
src="https://cdn.builder.io/api/v1/image/assets%2Ffc53d607e21d497595ac97e0637001a1%2F9a96b43cbd7b49bb9d5434580319c793?format=webp&width=800"
alt="Dev-Link"
className="h-8 w-8"
/>
<Button
onClick={() => navigate("/dev-link/profiles")}
variant="ghost"
className="text-cyan-300 hover:bg-cyan-500/10"
>
<ArrowLeft className="h-4 w-4 mr-2" />
Back to Profiles
</Button>
</div>
{/* Profile Card */}
<Card className="bg-cyan-950/30 border-cyan-400/30">
<CardHeader className="pb-0">
<div className="flex flex-col sm:flex-row gap-6 items-start">
{profile.avatar_url && (
<img
src={profile.avatar_url}
alt={profile.full_name}
className="w-24 h-24 sm:w-32 sm:h-32 rounded-full border-4 border-cyan-400/50"
/>
)}
<div className="flex-1">
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-4">
<div>
<CardTitle className="text-3xl sm:text-4xl text-cyan-300 mb-2">
{profile.full_name}
</CardTitle>
<Badge
variant="outline"
className={`capitalize ${getExperienceColor(
profile.experience_level,
)}`}
>
{profile.experience_level} Developer
</Badge>
</div>
<div className="flex gap-2">
<Button
variant="outline"
className="border-cyan-400/60 text-cyan-300 hover:bg-cyan-500/10"
>
<Share2 className="h-4 w-4 mr-2" />
Share
</Button>
<Button className="bg-cyan-400 text-black hover:bg-cyan-300">
<MessageSquare className="h-4 w-4 mr-2" />
Message
</Button>
</div>
</div>
{(profile.city || profile.country) && (
<div className="flex items-center gap-2 text-cyan-200/70 mb-4">
<MapPin className="h-4 w-4" />
<span>
{profile.city && profile.country
? `${profile.city}, ${profile.country}`
: profile.city || profile.country}
</span>
</div>
)}
</div>
</div>
</CardHeader>
<CardContent className="space-y-8">
{/* Bio */}
{profile.bio && (
<div>
<h3 className="text-lg font-semibold text-cyan-300 mb-2">
About
</h3>
<p className="text-cyan-200/80 leading-relaxed">
{profile.bio}
</p>
</div>
)}
{/* Looking For */}
{profile.looking_for && (
<div>
<h3 className="text-lg font-semibold text-cyan-300 mb-2">
Currently Looking For
</h3>
<p className="text-cyan-200/80 flex items-center gap-2">
<Briefcase className="h-5 w-5 text-cyan-400" />
{profile.looking_for}
</p>
</div>
)}
{/* Skills */}
{profile.skills && profile.skills.length > 0 && (
<div>
<h3 className="text-lg font-semibold text-cyan-300 mb-4">
Skills
</h3>
<div className="flex flex-wrap gap-3">
{profile.skills.map((skill) => (
<Badge
key={skill}
className="bg-cyan-500/20 text-cyan-300 border-cyan-400/40 border px-4 py-2"
>
{skill}
</Badge>
))}
</div>
</div>
)}
{/* Links */}
{(profile.github_url ||
profile.portfolio_url ||
profile.email) && (
<div>
<h3 className="text-lg font-semibold text-cyan-300 mb-4">
Connect
</h3>
<div className="flex flex-wrap gap-4">
{profile.github_url && (
<a
href={profile.github_url}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2 px-4 py-2 rounded-lg bg-cyan-500/10 border border-cyan-400/30 text-cyan-300 hover:border-cyan-400/60 hover:bg-cyan-500/20 transition"
>
<Github className="h-5 w-5" />
GitHub
<ExternalLink className="h-4 w-4" />
</a>
)}
{profile.portfolio_url && (
<a
href={profile.portfolio_url}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2 px-4 py-2 rounded-lg bg-cyan-500/10 border border-cyan-400/30 text-cyan-300 hover:border-cyan-400/60 hover:bg-cyan-500/20 transition"
>
<Trophy className="h-5 w-5" />
Portfolio
<ExternalLink className="h-4 w-4" />
</a>
)}
{profile.email && (
<a
href={`mailto:${profile.email}`}
className="flex items-center gap-2 px-4 py-2 rounded-lg bg-cyan-500/10 border border-cyan-400/30 text-cyan-300 hover:border-cyan-400/60 hover:bg-cyan-500/20 transition"
>
<Mail className="h-5 w-5" />
Email
</a>
)}
</div>
</div>
)}
{/* Member Since */}
<div className="pt-4 border-t border-cyan-400/20">
<p className="text-sm text-cyan-200/60">
Member since{" "}
{new Date(profile.created_at).toLocaleDateString()}
</p>
</div>
</CardContent>
</Card>
</div>
</section>
</main>
</div>
</Layout>
);
}

View file

@ -1,97 +0,0 @@
import Layout from "@/components/Layout";
import { Button } from "@/components/ui/button";
import { useNavigate, useLocation } from "react-router-dom";
import { ExternalLink } from "lucide-react";
export default function DevLinkProfiles() {
const navigate = useNavigate();
const location = useLocation();
const isWaitlist = location.pathname.includes("/waitlist");
return (
<Layout>
<div className="relative min-h-screen bg-black text-white overflow-hidden">
{/* Animated backgrounds */}
<div className="pointer-events-none absolute inset-0 opacity-[0.12] [background-image:radial-gradient(circle_at_top,#06b6d4_0,rgba(0,0,0,0.45)_55%,rgba(0,0,0,0.9)_100%)]" />
<div className="pointer-events-none absolute inset-0 bg-[linear-gradient(transparent_0,transparent_calc(100%-1px),rgba(6,182,212,0.05)_calc(100%-1px))] bg-[length:100%_32px]" />
<div className="pointer-events-none absolute inset-0 opacity-[0.08] [background-image:linear-gradient(90deg,rgba(6,182,212,0.1)_1px,transparent_1px),linear-gradient(0deg,rgba(6,182,212,0.1)_1px,transparent_1px)] [background-size:50px_50px] animate-pulse" />
<div className="pointer-events-none absolute top-20 left-10 w-72 h-72 bg-cyan-500/20 rounded-full blur-3xl animate-blob" />
<div className="pointer-events-none absolute bottom-20 right-10 w-72 h-72 bg-cyan-600/10 rounded-full blur-3xl animate-blob" />
<main className="relative z-10">
{/* Header */}
<section className="relative overflow-hidden py-12 lg:py-16">
<div className="container mx-auto max-w-6xl px-4">
<Button
onClick={() => navigate("/dev-link")}
variant="ghost"
className="text-cyan-300 hover:bg-cyan-500/10 mb-8"
>
Back to Dev-Link
</Button>
<div className="flex items-center justify-between mb-4">
<div>
<h1 className="text-4xl font-black tracking-tight text-cyan-300 sm:text-5xl mb-2">
{isWaitlist ? "Dev-Link Waitlist" : "Browse Profiles"}
</h1>
<p className="text-lg text-cyan-100/80 max-w-2xl">
{isWaitlist
? "Join the professional network for Roblox developers. Sign up for early access!"
: "Explore talented Roblox developers in our community."}
</p>
</div>
</div>
</div>
</section>
{/* Iframe Container */}
<section className="py-12 lg:py-16">
<div className="container mx-auto max-w-5xl px-4">
<div className="rounded-lg overflow-hidden border border-cyan-400/30 bg-cyan-950/20 shadow-[0_0_30px_rgba(6,182,212,0.2)]">
<iframe
src={
isWaitlist
? "https://dev-link.me/waitlist"
: "https://dev-link.me"
}
className="w-full border-0"
title={isWaitlist ? "Dev-Link Waitlist" : "Dev-Link Profiles"}
style={{
minHeight: "800px",
height: "80vh",
maxHeight: "800px",
}}
sandbox="allow-same-origin allow-scripts allow-popups allow-forms allow-top-navigation allow-top-navigation-by-user-activation"
allow="autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share"
/>
</div>
{/* Fallback Message */}
<div className="mt-12 text-center">
<p className="text-cyan-200/70 mb-4">
{isWaitlist
? "Having trouble loading the waitlist form?"
: "Having trouble loading the profiles?"}
</p>
<a
href={
isWaitlist
? "https://dev-link.me/waitlist"
: "https://dev-link.me"
}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 px-6 py-3 rounded-lg bg-cyan-500/20 border border-cyan-400/60 text-cyan-300 hover:bg-cyan-500/30 transition"
>
{isWaitlist ? "Visit Waitlist" : "Visit Profiles"} Directly
<ExternalLink className="h-4 w-4" />
</a>
</div>
</div>
</section>
</main>
</div>
</Layout>
);
}

View file

@ -1,404 +0,0 @@
import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import Layout from "@/components/Layout";
import { Button } from "@/components/ui/button";
import { useAuth } from "@/contexts/AuthContext";
import { useArmTheme } from "@/contexts/ArmThemeContext";
import { supabase } from "@/lib/supabase";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import LoadingScreen from "@/components/LoadingScreen";
import {
Code,
Users,
Briefcase,
ExternalLink,
ArrowRight,
AlertCircle,
Edit,
Save,
} from "lucide-react";
import { TeamWidget } from "@/components/TeamWidget";
const API_BASE = import.meta.env.VITE_API_BASE || "";
export default function DevLinkDashboard() {
const navigate = useNavigate();
const { user, loading: authLoading } = useAuth();
const { theme } = useArmTheme();
const [activeTab, setActiveTab] = useState("overview");
const [profile, setProfile] = useState<any>(null);
const [opportunities, setOpportunities] = useState<any[]>([]);
const [teams, setTeams] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [isEditing, setIsEditing] = useState(false);
useEffect(() => {
if (!authLoading && user) {
loadDashboardData();
}
}, [user, authLoading]);
const loadDashboardData = async () => {
try {
setLoading(true);
const {
data: { session },
} = await supabase.auth.getSession();
const token = session?.access_token;
if (!token) throw new Error("No auth token");
try {
const profileRes = await fetch(`${API_BASE}/api/devlink/profile`, {
headers: { Authorization: `Bearer ${token}` },
});
if (
profileRes.ok &&
profileRes.headers.get("content-type")?.includes("application/json")
) {
const data = await profileRes.json();
setProfile(data);
}
} catch (err) {
// Silently ignore API errors
}
try {
const oppRes = await fetch(`${API_BASE}/api/devlink/opportunities`, {
headers: { Authorization: `Bearer ${token}` },
});
if (
oppRes.ok &&
oppRes.headers.get("content-type")?.includes("application/json")
) {
const data = await oppRes.json();
setOpportunities(Array.isArray(data) ? data : []);
}
} catch (err) {
// Silently ignore API errors
}
try {
const teamsRes = await fetch(`${API_BASE}/api/devlink/teams`, {
headers: { Authorization: `Bearer ${token}` },
});
if (
teamsRes.ok &&
teamsRes.headers.get("content-type")?.includes("application/json")
) {
const data = await teamsRes.json();
setTeams(Array.isArray(data) ? data : []);
}
} catch (err) {
// Silently ignore API errors
}
} catch (error) {
// Silently ignore errors
} finally {
setLoading(false);
}
};
if (authLoading || loading) {
return <LoadingScreen message="Loading DEV-LINK..." />;
}
if (!user) {
return (
<Layout>
<div className="min-h-screen bg-gradient-to-b from-black via-cyan-950/30 to-black flex items-center justify-center px-4">
<div className="max-w-md text-center space-y-6">
<h1 className="text-4xl font-bold bg-gradient-to-r from-cyan-300 to-blue-300 bg-clip-text text-transparent">
DEV-LINK
</h1>
<p className="text-gray-400">Roblox Developer Network</p>
<Button
onClick={() => navigate("/login")}
className="w-full bg-gradient-to-r from-cyan-600 to-blue-600 hover:from-cyan-700 hover:to-blue-700 text-lg py-6"
>
Sign In
</Button>
</div>
</div>
</Layout>
);
}
return (
<Layout>
<div
className={`min-h-screen bg-gradient-to-b from-black to-black py-8 ${theme.fontClass}`}
style={{ backgroundImage: theme.wallpaperPattern }}
>
<div className="container mx-auto px-4 max-w-7xl space-y-8">
{/* Header */}
<div className="space-y-4 animate-slide-down">
<h1
className={`text-5xl md:text-6xl font-bold bg-gradient-to-r ${theme.accentColor} bg-clip-text text-transparent`}
>
DEV-LINK
</h1>
<p className="text-gray-400 text-lg">
Roblox Developer Network | Vibrant Cyan
</p>
</div>
{/* Tabs */}
<Tabs
value={activeTab}
onValueChange={setActiveTab}
className="w-full"
>
<TabsList
className="grid w-full grid-cols-4 bg-cyan-950/30 border border-cyan-500/20 p-1"
style={{ fontFamily: theme.fontFamily }}
>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="profile">Profile Editor</TabsTrigger>
<TabsTrigger value="jobs">Roblox Jobs</TabsTrigger>
<TabsTrigger value="teams">Teams</TabsTrigger>
</TabsList>
{/* Overview Tab */}
<TabsContent value="overview" className="space-y-6 animate-fade-in">
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<Card className="bg-gradient-to-br from-cyan-950/40 to-cyan-900/20 border-cyan-500/20">
<CardContent className="p-6 space-y-2">
<p className="text-sm text-gray-400">Profile Views</p>
<p className="text-3xl font-bold text-white">
{profile?.profile_views || 0}
</p>
</CardContent>
</Card>
<Card className="bg-gradient-to-br from-blue-950/40 to-blue-900/20 border-blue-500/20">
<CardContent className="p-6 space-y-2">
<p className="text-sm text-gray-400">Job Matches</p>
<p className="text-3xl font-bold text-white">
{opportunities.length}
</p>
</CardContent>
</Card>
<Card className="bg-gradient-to-br from-purple-950/40 to-purple-900/20 border-purple-500/20">
<CardContent className="p-6 space-y-2">
<p className="text-sm text-gray-400">Team Requests</p>
<p className="text-3xl font-bold text-white">
{teams.length}
</p>
</CardContent>
</Card>
</div>
{/* Quick Links */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<Card className="bg-gradient-to-br from-cyan-600/20 to-blue-600/20 border-cyan-500/40">
<CardContent className="p-6 text-center space-y-4">
<h3
className="text-lg font-bold text-white"
style={{ fontFamily: theme.fontFamily }}
>
Browse Roblox Jobs
</h3>
<Button
onClick={() => navigate("/dev-link/jobs")}
variant="outline"
className="w-full border-cyan-500/30 text-cyan-300 hover:bg-cyan-500/10"
style={{ fontFamily: theme.fontFamily }}
>
<ExternalLink className="h-4 w-4 mr-2" />
View All Roblox Jobs
</Button>
</CardContent>
</Card>
<Card className="bg-gradient-to-br from-blue-600/20 to-purple-600/20 border-blue-500/40">
<CardContent className="p-6 text-center space-y-4">
<h3
className="text-lg font-bold text-white"
style={{ fontFamily: theme.fontFamily }}
>
Find a Teammate
</h3>
<Button
onClick={() => navigate("/dev-link/teams")}
variant="outline"
className="w-full border-blue-500/30 text-blue-300 hover:bg-blue-500/10"
style={{ fontFamily: theme.fontFamily }}
>
<Users className="h-4 w-4 mr-2" />
Search Teams
</Button>
</CardContent>
</Card>
</div>
</TabsContent>
{/* Profile Editor Tab */}
<TabsContent value="profile" className="space-y-4 animate-fade-in">
<Card className="bg-gradient-to-br from-cyan-950/40 to-cyan-900/20 border-cyan-500/20">
<CardHeader>
<CardTitle className="flex items-center justify-between">
<span>My dev-link Profile Editor</span>
<Button
size="sm"
variant="outline"
className="border-cyan-500/30"
onClick={() => setIsEditing(!isEditing)}
>
{isEditing ? (
<Save className="h-4 w-4 mr-2" />
) : (
<Edit className="h-4 w-4 mr-2" />
)}
{isEditing ? "Save" : "Edit"}
</Button>
</CardTitle>
<CardDescription>
Customize your Roblox portfolio
</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
{/* Roblox Creations */}
<div className="space-y-3">
<h3 className="font-semibold text-white">
My Roblox Creations
</h3>
{isEditing ? (
<textarea
className="w-full px-4 py-2 bg-black/30 border border-cyan-500/20 rounded-lg text-white placeholder-gray-500"
placeholder="List your Roblox creations and projects..."
defaultValue={profile?.creations || ""}
rows={4}
/>
) : (
<p className="text-gray-400">
{profile?.creations || "No creations listed yet"}
</p>
)}
</div>
{/* Experiences */}
<div className="space-y-3">
<h3 className="font-semibold text-white">
My Experiences (Asset IDs)
</h3>
{isEditing ? (
<textarea
className="w-full px-4 py-2 bg-black/30 border border-cyan-500/20 rounded-lg text-white placeholder-gray-500"
placeholder="List your Roblox experience IDs..."
defaultValue={profile?.experiences || ""}
rows={4}
/>
) : (
<p className="text-gray-400">
{profile?.experiences || "No experiences listed yet"}
</p>
)}
</div>
{/* Certifications */}
<div className="space-y-3">
<h3 className="font-semibold text-white">
EdTech Certifications
</h3>
{isEditing ? (
<textarea
className="w-full px-4 py-2 bg-black/30 border border-cyan-500/20 rounded-lg text-white placeholder-gray-500"
placeholder="List your FOUNDATION course certifications..."
defaultValue={profile?.certifications || ""}
rows={3}
/>
) : (
<p className="text-gray-400">
{profile?.certifications ||
"No certifications listed yet"}
</p>
)}
</div>
</CardContent>
</Card>
</TabsContent>
{/* Roblox Job Feed Tab */}
<TabsContent value="jobs" className="space-y-4 animate-fade-in">
<Card className="bg-gradient-to-br from-cyan-950/40 to-cyan-900/20 border-cyan-500/20">
<CardHeader>
<CardTitle>Roblox Job Feed</CardTitle>
<CardDescription>
Pre-filtered DEV-LINK opportunities
</CardDescription>
</CardHeader>
<CardContent>
{opportunities.length === 0 ? (
<div className="text-center py-12">
<Briefcase className="h-12 w-12 mx-auto text-gray-500 opacity-50 mb-4" />
<p className="text-gray-400">
No matching jobs at this time
</p>
</div>
) : (
<div className="space-y-3">
{opportunities.map((job: any) => (
<div
key={job.id}
className="p-4 bg-black/30 rounded-lg border border-cyan-500/10 hover:border-cyan-500/30 transition"
>
<div className="flex items-start justify-between gap-4 mb-2">
<h4 className="font-semibold text-white">
{job.title}
</h4>
<Badge className="bg-cyan-600/50 text-cyan-100">
Roblox
</Badge>
</div>
<p className="text-sm text-gray-400">
{job.description?.substring(0, 100)}...
</p>
<p className="text-sm font-semibold text-white mt-2">
${job.budget?.toLocaleString()}
</p>
<Button
size="sm"
variant="outline"
className="mt-3 border-cyan-500/30 text-cyan-300 hover:bg-cyan-500/10"
>
View Details <ArrowRight className="h-3 w-3 ml-2" />
</Button>
</div>
))}
</div>
)}
</CardContent>
</Card>
</TabsContent>
{/* Teams Tab */}
<TabsContent value="teams" className="space-y-4 animate-fade-in">
<TeamWidget
members={teams.flatMap((t: any) =>
(t.members || []).map((m: any) => ({
id: m.id,
name: m.full_name,
role: m.role || "Member",
type: m.role === "lead" ? "lead" : "member",
avatar: m.avatar_url,
team_name: t.name,
})),
)}
title="My dev-link Teams"
description="Find and manage Roblox development teams"
accentColor="cyan"
onMemberClick={() => {}}
/>
</TabsContent>
</Tabs>
</div>
</div>
</Layout>
);
}

View file

@ -1,180 +0,0 @@
import Layout from "@/components/Layout";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent } from "@/components/ui/card";
import { Users, Zap, Target, Heart, ArrowRight } from "lucide-react";
import { useNavigate } from "react-router-dom";
export default function DevLinkAbout() {
const navigate = useNavigate();
const values = [
{
icon: Users,
title: "Community First",
description: "Built by Roblox creators, for Roblox creators",
},
{
icon: Zap,
title: "Empower",
description: "Help developers connect and grow together",
},
{
icon: Target,
title: "Professional",
description: "A platform that takes Roblox development seriously",
},
{
icon: Heart,
title: "Inclusive",
description: "Supporting developers at all skill levels",
},
];
const milestones = [
{ year: "2024", event: "Dev-Link Founded", status: "Complete" },
{ year: "2025", event: "Beta Launch", status: "In Progress" },
{ year: "2025", event: "Public Release", status: "Q2" },
{ year: "2025", event: "Job Board Launch", status: "Q3" },
];
return (
<Layout>
<div className="relative min-h-screen bg-black text-white overflow-hidden">
<div className="pointer-events-none absolute inset-0 opacity-[0.12] [background-image:radial-gradient(circle_at_top,#06b6d4_0,rgba(0,0,0,0.45)_55%,rgba(0,0,0,0.9)_100%)]" />
<div className="pointer-events-none absolute inset-0 bg-[linear-gradient(transparent_0,transparent_calc(100%-1px),rgba(6,182,212,0.05)_calc(100%-1px))] bg-[length:100%_32px]" />
<div className="pointer-events-none absolute inset-0 opacity-[0.08] [background-image:linear-gradient(90deg,rgba(6,182,212,0.1)_1px,transparent_1px),linear-gradient(0deg,rgba(6,182,212,0.1)_1px,transparent_1px)] [background-size:50px_50px] animate-pulse" />
<div className="pointer-events-none absolute top-20 left-10 w-72 h-72 bg-cyan-500/20 rounded-full blur-3xl animate-blob" />
<div className="pointer-events-none absolute bottom-20 right-10 w-72 h-72 bg-cyan-600/10 rounded-full blur-3xl animate-blob animation-delay-2000" />
<main className="relative z-10">
<section className="py-16">
<div className="container mx-auto max-w-6xl px-4">
<Button
variant="ghost"
className="text-cyan-300 hover:bg-cyan-500/10 mb-8"
onClick={() => navigate("/dev-link")}
>
Back to Dev-Link
</Button>
<h1 className="text-4xl lg:text-5xl font-black text-cyan-300 mb-4">
About Dev-Link
</h1>
<p className="text-lg text-cyan-100/80 max-w-3xl">
The professional networking platform built for Roblox
developers. Connect, collaborate, and grow your career in game
development.
</p>
</div>
</section>
<section className="py-16">
<div className="container mx-auto max-w-6xl px-4">
<h2 className="text-3xl font-bold text-cyan-300 mb-8">
Our Mission
</h2>
<Card className="bg-cyan-950/20 border-cyan-400/30">
<CardContent className="pt-6">
<p className="text-lg text-cyan-200/80 leading-relaxed">
Dev-Link is on a mission to empower Roblox developers
worldwide. We believe that the Roblox platform has created
an incredible community of creators who deserve a
professional space to connect, showcase their work, and find
amazing opportunities. Just like LinkedIn transformed
professional networking, Dev-Link is transforming how Roblox
developers collaborate and build their careers.
</p>
</CardContent>
</Card>
</div>
</section>
<section className="py-16 border-t border-cyan-400/10 bg-black/40">
<div className="container mx-auto max-w-6xl px-4">
<h2 className="text-3xl font-bold text-cyan-300 mb-8">
Our Values
</h2>
<div className="grid md:grid-cols-2 gap-6">
{values.map((value, idx) => {
const Icon = value.icon;
return (
<Card
key={idx}
className="bg-cyan-950/20 border-cyan-400/30"
>
<CardContent className="pt-6">
<Icon className="h-8 w-8 text-cyan-400 mb-3" />
<h3 className="text-lg font-bold text-cyan-300 mb-2">
{value.title}
</h3>
<p className="text-sm text-cyan-200/70">
{value.description}
</p>
</CardContent>
</Card>
);
})}
</div>
</div>
</section>
<section className="py-16">
<div className="container mx-auto max-w-6xl px-4">
<h2 className="text-3xl font-bold text-cyan-300 mb-8">
Our Roadmap
</h2>
<div className="space-y-4">
{milestones.map((milestone, idx) => (
<Card key={idx} className="bg-cyan-950/20 border-cyan-400/30">
<CardContent className="pt-6">
<div className="flex items-center justify-between">
<div>
<Badge className="bg-cyan-500/20 text-cyan-300 border border-cyan-400/40 mb-2">
{milestone.year}
</Badge>
<p className="font-bold text-cyan-300">
{milestone.event}
</p>
</div>
<Badge
className={`${
milestone.status === "Complete"
? "bg-green-500/20 text-green-300"
: milestone.status === "In Progress"
? "bg-yellow-500/20 text-yellow-300"
: "bg-cyan-500/20 text-cyan-300"
} border`}
>
{milestone.status}
</Badge>
</div>
</CardContent>
</Card>
))}
</div>
</div>
</section>
<section className="py-16 border-t border-cyan-400/10">
<div className="container mx-auto max-w-4xl px-4 text-center">
<h2 className="text-3xl font-bold text-cyan-300 mb-4">
Join the Community
</h2>
<p className="text-lg text-cyan-100/80 mb-8">
Be part of the professional Roblox developer community
</p>
<Button
className="bg-cyan-400 text-black shadow-[0_0_30px_rgba(6,182,212,0.35)] hover:bg-cyan-300"
onClick={() => navigate("/dev-link/waitlist")}
>
Join Waitlist
<ArrowRight className="ml-2 h-4 w-4" />
</Button>
</div>
</section>
</main>
</div>
</Layout>
);
}

View file

@ -1,186 +0,0 @@
import Layout from "@/components/Layout";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent } from "@/components/ui/card";
import { Briefcase, MapPin, DollarSign, Clock, ArrowRight } from "lucide-react";
import { useNavigate } from "react-router-dom";
export default function DevLinkJobs() {
const navigate = useNavigate();
const jobs = [
{
title: "Senior Roblox Developer",
company: "Studio XYZ",
type: "Full-time",
location: "Remote",
salary: "$120K - $150K/yr",
description: "Lead development on flagship title with 100K+ players",
skills: ["Roblox", "Lua", "Leadership"],
},
{
title: "Game Designer",
company: "Creative Games Inc",
type: "Contract",
location: "Remote",
salary: "$80/hr",
description: "Design gameplay systems for new multiplayer game",
skills: ["Game Design", "Roblox", "Balancing"],
},
{
title: "UI/UX Designer",
company: "Pixel Studios",
type: "Part-time",
location: "Remote",
salary: "$50/hr",
description: "Create beautiful interfaces for mobile game",
skills: ["UI Design", "Roblox", "User Research"],
},
{
title: "Backend Engineer",
company: "GameTech Corp",
type: "Full-time",
location: "Hybrid",
salary: "$130K - $170K/yr",
description: "Build scalable backend systems for multiplayer platform",
skills: ["Backend", "Systems Design", "Databases"],
},
{
title: "Audio Engineer",
company: "Sound Studios",
type: "Contract",
location: "Remote",
salary: "$75/hr",
description: "Compose and implement audio for 5-game project",
skills: ["Audio Design", "Music Composition", "SFX"],
},
{
title: "QA Tester",
company: "Quality First Games",
type: "Full-time",
location: "Remote",
salary: "$60K - $80K/yr",
description: "Comprehensive testing on multiplayer platform",
skills: ["QA", "Testing", "Roblox"],
},
];
return (
<Layout>
<div className="relative min-h-screen bg-black text-white overflow-hidden">
<div className="pointer-events-none absolute inset-0 opacity-[0.12] [background-image:radial-gradient(circle_at_top,#06b6d4_0,rgba(0,0,0,0.45)_55%,rgba(0,0,0,0.9)_100%)]" />
<div className="pointer-events-none absolute inset-0 bg-[linear-gradient(transparent_0,transparent_calc(100%-1px),rgba(6,182,212,0.05)_calc(100%-1px))] bg-[length:100%_32px]" />
<div className="pointer-events-none absolute inset-0 opacity-[0.08] [background-image:linear-gradient(90deg,rgba(6,182,212,0.1)_1px,transparent_1px),linear-gradient(0deg,rgba(6,182,212,0.1)_1px,transparent_1px)] [background-size:50px_50px] animate-pulse" />
<div className="pointer-events-none absolute top-20 left-10 w-72 h-72 bg-cyan-500/20 rounded-full blur-3xl animate-blob" />
<div className="pointer-events-none absolute bottom-20 right-10 w-72 h-72 bg-cyan-600/10 rounded-full blur-3xl animate-blob animation-delay-2000" />
<main className="relative z-10">
<section className="py-16">
<div className="container mx-auto max-w-6xl px-4">
<Button
variant="ghost"
className="text-cyan-300 hover:bg-cyan-500/10 mb-8"
onClick={() => navigate("/dev-link")}
>
Back to Dev-Link
</Button>
<h1 className="text-4xl lg:text-5xl font-black text-cyan-300 mb-4">
Job Board
</h1>
<p className="text-lg text-cyan-100/80 max-w-3xl">
Find your next opportunity in the Roblox ecosystem. Full-time,
part-time, and contract roles available.
</p>
</div>
</section>
<section className="py-16">
<div className="container mx-auto max-w-6xl px-4">
<div className="space-y-4">
{jobs.map((job, idx) => (
<Card
key={idx}
className="bg-cyan-950/20 border-cyan-400/30 hover:border-cyan-400/60 transition-all cursor-pointer"
>
<CardContent className="pt-6">
<div className="grid md:grid-cols-2 gap-6">
<div>
<h3 className="text-xl font-bold text-cyan-300 mb-1">
{job.title}
</h3>
<p className="text-sm text-cyan-400 font-medium mb-3">
{job.company}
</p>
<p className="text-sm text-cyan-200/70 mb-4">
{job.description}
</p>
</div>
<div className="space-y-3">
<div className="flex items-center gap-3">
<Badge
className={`${
job.type === "Full-time"
? "bg-green-500/20 text-green-300 border border-green-400/40"
: "bg-cyan-500/20 text-cyan-300 border border-cyan-400/40"
}`}
>
{job.type}
</Badge>
<span className="flex items-center gap-1 text-sm text-cyan-200/70">
<MapPin className="h-4 w-4" />
{job.location}
</span>
</div>
<div className="flex items-center gap-2 text-lg font-bold text-cyan-300">
<DollarSign className="h-5 w-5" />
{job.salary}
</div>
<div className="flex flex-wrap gap-2">
{job.skills.map((skill, i) => (
<Badge
key={i}
className="bg-cyan-500/20 text-cyan-300 border border-cyan-400/40 text-xs"
>
{skill}
</Badge>
))}
</div>
<Button
className="w-full bg-cyan-400 text-black hover:bg-cyan-300"
size="sm"
>
Apply Now
</Button>
</div>
</div>
</CardContent>
</Card>
))}
</div>
</div>
</section>
<section className="py-16 border-t border-cyan-400/10">
<div className="container mx-auto max-w-4xl px-4 text-center">
<h2 className="text-3xl font-bold text-cyan-300 mb-4">
Hiring? Post a Job
</h2>
<p className="text-lg text-cyan-100/80 mb-8">
Reach 50K+ talented Roblox developers.
</p>
<Button className="bg-cyan-400 text-black hover:bg-cyan-300">
Post a Job Opening
<ArrowRight className="ml-2 h-4 w-4" />
</Button>
</div>
</section>
</main>
</div>
</Layout>
);
}

View file

@ -1,191 +0,0 @@
import Layout from "@/components/Layout";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent } from "@/components/ui/card";
import { Search, Star, Users, ArrowRight, Github } from "lucide-react";
import { useNavigate, useState } from "react-router-dom";
export default function DevLinkProfiles() {
const navigate = useNavigate();
const [searchQuery, setSearchQuery] = useState("");
const developers = [
{
name: "Alex Rivera",
title: "Roblox Game Developer",
skills: ["Roblox", "Lua", "Game Design"],
portfolio: "3 games shipped",
rating: 4.9,
available: true,
},
{
name: "Jordan Chen",
title: "Full Stack Developer",
skills: ["Roblox", "TypeScript", "Backend"],
portfolio: "5 projects",
rating: 4.8,
available: true,
},
{
name: "Sam Taylor",
title: "UI/UX Designer",
skills: ["Game UI", "Roblox", "Design"],
portfolio: "10+ designs",
rating: 4.7,
available: false,
},
{
name: "Morgan Lee",
title: "Audio Engineer",
skills: ["Game Audio", "Music", "Sound Design"],
portfolio: "15+ games",
rating: 4.9,
available: true,
},
{
name: "Casey Williams",
title: "Technical Lead",
skills: ["Architecture", "Roblox", "Leadership"],
portfolio: "Lead on 20+ games",
rating: 5.0,
available: false,
},
{
name: "Riley Martinez",
title: "Gameplay Programmer",
skills: ["Game Logic", "Roblox", "C++"],
portfolio: "8 shipped titles",
rating: 4.8,
available: true,
},
];
return (
<Layout>
<div className="relative min-h-screen bg-black text-white overflow-hidden">
<div className="pointer-events-none absolute inset-0 opacity-[0.12] [background-image:radial-gradient(circle_at_top,#06b6d4_0,rgba(0,0,0,0.45)_55%,rgba(0,0,0,0.9)_100%)]" />
<div className="pointer-events-none absolute inset-0 bg-[linear-gradient(transparent_0,transparent_calc(100%-1px),rgba(6,182,212,0.05)_calc(100%-1px))] bg-[length:100%_32px]" />
<div className="pointer-events-none absolute inset-0 opacity-[0.08] [background-image:linear-gradient(90deg,rgba(6,182,212,0.1)_1px,transparent_1px),linear-gradient(0deg,rgba(6,182,212,0.1)_1px,transparent_1px)] [background-size:50px_50px] animate-pulse" />
<div className="pointer-events-none absolute top-20 left-10 w-72 h-72 bg-cyan-500/20 rounded-full blur-3xl animate-blob" />
<div className="pointer-events-none absolute bottom-20 right-10 w-72 h-72 bg-cyan-600/10 rounded-full blur-3xl animate-blob animation-delay-2000" />
<main className="relative z-10">
<section className="py-16">
<div className="container mx-auto max-w-6xl px-4">
<Button
variant="ghost"
className="text-cyan-300 hover:bg-cyan-500/10 mb-8"
onClick={() => navigate("/dev-link")}
>
Back to Dev-Link
</Button>
<h1 className="text-4xl lg:text-5xl font-black text-cyan-300 mb-4">
Developer Directory
</h1>
<p className="text-lg text-cyan-100/80 max-w-3xl">
Find and connect with talented Roblox developers, browse
portfolios, and discover collaboration opportunities.
</p>
</div>
</section>
<section className="py-8">
<div className="container mx-auto max-w-6xl px-4">
<div className="relative">
<Search className="absolute left-4 top-3 h-5 w-5 text-cyan-400" />
<input
type="text"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
placeholder="Search by name, skill, or role..."
className="w-full pl-12 pr-4 py-3 bg-cyan-950/40 border border-cyan-400/30 rounded-lg text-cyan-300 placeholder-cyan-400/50 focus:outline-none focus:border-cyan-400/60"
/>
</div>
</div>
</section>
<section className="py-16">
<div className="container mx-auto max-w-6xl px-4">
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{developers.map((dev, idx) => (
<Card
key={idx}
className="bg-cyan-950/20 border-cyan-400/30 hover:border-cyan-400/60 transition-all cursor-pointer"
>
<CardContent className="pt-6">
<div className="flex items-start justify-between mb-4">
<div className="w-12 h-12 rounded-full bg-gradient-to-r from-cyan-500 to-blue-500 flex items-center justify-center text-white font-bold">
{dev.name
.split(" ")
.map((n) => n[0])
.join("")}
</div>
{dev.available && (
<Badge className="bg-green-500/20 text-green-300 border border-green-400/40 text-xs">
Available
</Badge>
)}
</div>
<h3 className="text-lg font-bold text-cyan-300 mb-1">
{dev.name}
</h3>
<p className="text-sm text-cyan-400 font-medium mb-4">
{dev.title}
</p>
<div className="flex flex-wrap gap-2 mb-4">
{dev.skills.map((skill, i) => (
<Badge
key={i}
className="bg-cyan-500/20 text-cyan-300 border border-cyan-400/40 text-xs"
>
{skill}
</Badge>
))}
</div>
<div className="pt-4 border-t border-cyan-400/10 space-y-3">
<div className="flex justify-between text-sm">
<span className="text-cyan-200/70">
{dev.portfolio}
</span>
<span className="flex items-center gap-1 text-yellow-400">
<Star className="h-4 w-4 fill-yellow-400" />
{dev.rating}
</span>
</div>
<Button
className="w-full bg-cyan-400 text-black hover:bg-cyan-300"
size="sm"
>
View Profile
</Button>
</div>
</CardContent>
</Card>
))}
</div>
</div>
</section>
<section className="py-16 border-t border-cyan-400/10">
<div className="container mx-auto max-w-4xl px-4 text-center">
<h2 className="text-3xl font-bold text-cyan-300 mb-4">
Create Your Profile
</h2>
<p className="text-lg text-cyan-100/80 mb-8">
Showcase your work and connect with other developers.
</p>
<Button className="bg-cyan-400 text-black hover:bg-cyan-300">
Get Started
<ArrowRight className="ml-2 h-4 w-4" />
</Button>
</div>
</section>
</main>
</div>
</Layout>
);
}

View file

@ -1,145 +0,0 @@
import Layout from "@/components/Layout";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Users, Github, Mail, Linkedin } from "lucide-react";
import { useNavigate } from "react-router-dom";
const TEAM_MEMBERS = [
{
name: "Amanda Foster",
role: "Platform Lead",
bio: "Building the future of developer networking",
avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=Amanda",
skills: ["Platform", "Product", "Leadership"],
social: { github: "#", linkedin: "#", email: "#" },
},
{
name: "Chris Martinez",
role: "Community Lead",
bio: "Fostering connections between developers",
avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=Chris",
skills: ["Community", "Engagement", "Growth"],
social: { github: "#", linkedin: "#", email: "#" },
},
{
name: "Priya Sharma",
role: "Product Manager",
bio: "Shaping the future of Dev-Link platform",
avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=Priya",
skills: ["Product", "Strategy", "Design"],
social: { github: "#", linkedin: "#", email: "#" },
},
{
name: "Marcus Williams",
role: "Engineering Lead",
bio: "Building robust and scalable infrastructure",
avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=Marcus",
skills: ["Engineering", "Infrastructure", "Scaling"],
social: { github: "#", linkedin: "#", email: "#" },
},
];
export default function DevLinkTeams() {
const navigate = useNavigate();
return (
<Layout>
<div className="relative min-h-screen bg-black text-white overflow-hidden">
{/* Animated backgrounds */}
<div className="pointer-events-none absolute inset-0 opacity-[0.12] [background-image:radial-gradient(circle_at_top,#06b6d4_0,rgba(0,0,0,0.45)_55%,rgba(0,0,0,0.9)_100%)]" />
<div className="pointer-events-none absolute inset-0 bg-[linear-gradient(transparent_0,transparent_calc(100%-1px),rgba(6,182,212,0.05)_calc(100%-1px))] bg-[length:100%_32px]" />
<div className="pointer-events-none absolute inset-0 opacity-[0.08] [background-image:linear-gradient(90deg,rgba(6,182,212,0.1)_1px,transparent_1px),linear-gradient(0deg,rgba(6,182,212,0.1)_1px,transparent_1px)] [background-size:50px_50px] animate-pulse" />
<div className="pointer-events-none absolute top-20 left-10 w-72 h-72 bg-cyan-500/20 rounded-full blur-3xl animate-blob" />
<div className="pointer-events-none absolute bottom-20 right-10 w-72 h-72 bg-cyan-600/10 rounded-full blur-3xl animate-blob" />
<main className="relative z-10">
{/* Header */}
<section className="relative overflow-hidden py-12 lg:py-16">
<div className="container mx-auto max-w-6xl px-4">
<Button
onClick={() => navigate("/dev-link")}
variant="ghost"
className="text-cyan-300 hover:bg-cyan-500/10 mb-8"
>
Back to Dev-Link
</Button>
<div className="mb-12">
<Badge className="border-cyan-400/40 bg-cyan-500/10 text-cyan-300 mb-4">
<Users className="h-4 w-4 mr-2" />
Our Team
</Badge>
<h1 className="text-4xl font-black tracking-tight text-cyan-300 sm:text-5xl mb-4">
Meet the Dev-Link Team
</h1>
<p className="text-lg text-cyan-100/80 max-w-2xl">
Connecting Roblox developers worldwide
</p>
</div>
</div>
</section>
{/* Team Grid */}
<section className="py-12 lg:py-16">
<div className="container mx-auto max-w-6xl px-4">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-12">
{TEAM_MEMBERS.map((member) => (
<Card
key={member.name}
className="bg-cyan-950/20 border-cyan-400/30 hover:border-cyan-400/60 hover:bg-cyan-950/30 transition-all"
>
<CardHeader className="text-center">
<img
src={member.avatar}
alt={member.name}
className="w-20 h-20 rounded-full mx-auto mb-4 border-2 border-cyan-400/50"
/>
<CardTitle className="text-cyan-300">{member.name}</CardTitle>
<p className="text-sm text-cyan-200/70 mt-1">{member.role}</p>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-sm text-cyan-200/70">{member.bio}</p>
<div className="flex flex-wrap gap-2">
{member.skills.map((skill) => (
<Badge
key={skill}
className="bg-cyan-500/20 text-cyan-300 border-0 text-xs"
>
{skill}
</Badge>
))}
</div>
<div className="flex gap-3 pt-2">
<a href={member.social.github} className="text-cyan-400 hover:text-cyan-300">
<Github className="h-5 w-5" />
</a>
<a href={member.social.linkedin} className="text-cyan-400 hover:text-cyan-300">
<Linkedin className="h-5 w-5" />
</a>
<a href={member.social.email} className="text-cyan-400 hover:text-cyan-300">
<Mail className="h-5 w-5" />
</a>
</div>
</CardContent>
</Card>
))}
</div>
{/* Hiring Section */}
<div className="rounded-lg border border-cyan-400/30 bg-cyan-950/20 p-8 text-center">
<h2 className="text-2xl font-bold text-cyan-300 mb-4">Join Dev-Link</h2>
<p className="text-cyan-200/80 mb-6 max-w-2xl mx-auto">
Help us build the professional network for Roblox developers
</p>
<Button className="bg-cyan-400 text-black hover:bg-cyan-300">
View Open Positions
</Button>
</div>
</div>
</section>
</main>
</div>
</Layout>
);
}