Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions app/(public)/flex/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { createClient } from "../../lib/supabase/server";
import Footer from "@/app/components/layout/Footer";
import CTA from "@/app/components/layout/CTA";
import BackButton from "@/app/components/leaderboard/BackButton";
import Image from "next/image";
import { timeAgo } from "@/app/utils/time";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faExternalLink } from "@fortawesome/free-solid-svg-icons";

export default async function Flexs() {
const supabase = await createClient();

const [userFlexes, userResult] = await Promise.all([
supabase
.from("user_flexes")
.select("*")
.order("created_at", { ascending: false }),
supabase.auth.getUser(),
]);

const { data, error } = userFlexes;
const { data: user } = userResult;

return (
<div className="min-h-screen bg-[#0a0a1a] text-white grid-bg relative">
<div className="max-w-5xl mx-auto p-6 md:p-10 relative z-10">
<BackButton href="/" />

<div className="flex justify-center items-center gap-3 mb-8">
<Image src="/logo.svg" alt="DevPulse Logo" width={36} height={36} />
<h1 className="text-3xl font-bold text-white">DevPulse Flexes</h1>
</div>

{data?.length === 0 && (
<div className="max-w-5xl mx-auto p-6 md:p-10 relative z-10">
<h2 className="text-2xl font-bold mb-4">No Flexes Yet</h2>
<p className="text-gray-400 mb-6">
Please come back later to see the latest flexes from our
community.
</p>
</div>
)}

{data && data.length > 0 && (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{data.map((flex) => (
<div
key={flex.id}
className="glass-card p-6 rounded-xl border border-white/5"
>
<div className="flex items-center justify-between">
<h3 className="text-lg font-semibold mb-2">
{flex.project_name}
</h3>
<span className="text-sm">{timeAgo(flex.created_at)}</span>
</div>
<div className="text-sm text-gray-500 mb-4">
{flex.project_time}
</div>
<span className="font-bold text-xs text-gray-400">
Description:
</span>
<p className="text-gray-400 mb-2">{flex.project_description}</p>
{flex.is_open_source && (
<>
<span className="font-bold text-xs text-gray-400">
Open Source:
</span>
<a
href={flex.open_source_url}
target="_blank"
rel="noopener noreferrer"
className="text-sm block underline hover:text-green-300 transition mb-2 truncate"
>
{flex.open_source_url}
</a>
</>
)}
<div className="flex items-center justify-between mt-4">
<p className="text-sm text-gray-500">
Posted by {flex.user_email.split("@")[0]}
</p>
<a
href={flex.project_url}
target="_blank"
rel="noopener noreferrer"
>
<FontAwesomeIcon
icon={faExternalLink}
className="w-4 h-4 text-gray-400 hover:text-gray-300 transition"
/>
</a>
</div>
</div>
))}
</div>
)}
</div>

{!user && <CTA />}
<Footer />
</div>
);
}
14 changes: 14 additions & 0 deletions app/(user)/dashboard/flex/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Flex from "@/app/components/Flex";
import { createClient } from "@/app/lib/supabase/server";

export default async function FlexPage() {
const supabase = await createClient();

const {
data: { user },
} = await supabase.auth.getUser();

if (!user) return null;

return <Flex user={user} />;
}
20 changes: 12 additions & 8 deletions app/components/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ export default function Chat({ user }: { user: User }) {
const [badgesByUserId, setBadgesByUserId] = useState<
Record<string, { label: string; className: string }>
>({});
const badgeCacheRef = useRef<Record<string, { label: string; className: string }>>({});
const badgeCacheRef = useRef<
Record<string, { label: string; className: string }>
>({});
const channelRef = useRef<RealtimeChannel>(null);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const bottomRef = useRef<HTMLDivElement | null>(null);
Expand Down Expand Up @@ -662,7 +664,7 @@ export default function Chat({ user }: { user: User }) {
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search user..."
className="w-full mb-3 px-3 py-2 rounded bg-neutral-800 outline-none"
className="w-full mb-3 px-3 py-2 bg-transparent text-gray-100 placeholder:text-gray-500 border border-neutral-800 rounded-xl outline-none"
/>
<div className="space-y-2 max-h-60 overflow-y-auto">
{allUsers
Expand All @@ -684,12 +686,14 @@ export default function Chat({ user }: { user: User }) {
</div>
))}
</div>
<button
onClick={() => setShowModal(false)}
className="mt-4 text-sm text-gray-500 hover:text-gray-300 transition"
>
Cancel
</button>
<div className="flex justify-end mt-4">
<button
onClick={() => setShowModal(false)}
className="mt-4 btn-secondary px-4 py-2 text-sm rounded-xl me-2"
>
Cancel
</button>
</div>
</div>
</div>
)}
Expand Down
Loading
Loading