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:
parent
2ff1292bf6
commit
ee1e052094
9 changed files with 5 additions and 1732 deletions
|
|
@ -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 */}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue