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
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { BadgeCheck } from "lucide-react";
import React from "react";

function DiscussionItem(props: {
live?: boolean;
title: string;
author: string;
excerpt: string;
}) {
const { live, title, author, excerpt } = props;
return (
<div className="border rounded-[8px] border-[#E7E7E7] p-4">
<div className="flex gap-4 items-stretch">
<div className="w-[130px] rounded-md bg-[#D9D9D9]" />
<div className="flex-1">
{live && (
<span className="text-[11px] bg-[#FF5C5C] text-white rounded-full px-2 py-[1px]">
Live
</span>
)}
<h3 className="font-semibold text-[#222] text-[22px]/4 my-1">
{title}
</h3>
<div className="text-sm text-[#5D5D5D] flex items-center gap-1">
By {author} <BadgeCheck size={14} className="text-[#3B82F6]" />
</div>
<div className="text-xs text-[#888888] mb-1 mt-4">
Book Description
</div>
<div className="mt-2 text-base/6 text-[#888888]">{excerpt}</div>
{!live && (
<div className="mt-3 text-xs text-[#9A9A9A]">2 weeks ago</div>
)}
</div>
</div>
</div>
);
}

export default DiscussionItem;
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from "react";
import { Community } from "../../utills/data";
import { ClipboardList, Earth, Users } from "lucide-react";

function Tag({ children }: { children: React.ReactNode }) {
return (
<div className="inline-flex items-center gap-1 py-[2px] px-[8px] border border-[#E4E4E4] rounded-full text-[#8A8A8A] text-xs">
{children}
</div>
);
}

function DiscussionSummary({ community }: { community: Community }) {
return (
<div
className="border border-[#EFEFEF] rounded-[8px] p-4 bg-white flex gap-4 items-stretch"
style={{ boxShadow: "0px 6px 6px 0px #1212120A" }}
>
<div className="w-[140px] bg-[#D9D9D9] rounded-md" />
<div className="flex-1">
<h2 className="text-2xl/8 mb-2 font-semibold text-[#333]">
{community.name}
</h2>
<p className="text-base text-[#888888] max-w-[900px]">
{community.description}
</p>
<div className="mt-4 flex flex-wrap gap-4">
<Tag>
<Earth size={12} /> {community.visibility}
</Tag>
<Tag>
<Users size={12} /> {community.membersLabel}
</Tag>
<Tag>
<ClipboardList size={12} /> {community.sessionsLabel}
</Tag>
</div>
</div>
</div>
);
}

export default DiscussionSummary;
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import DiscussionItem from "./DiscussionItem";

function DiscussionsTab() {
return (
<>
<DiscussionItem
live
title="Native Invisibility"
author="Darrin Collins"
excerpt="Delves into the complex and often insidious ways in which indigenous peoples and their unique experiences are rendered unseen and unheard in the modern era."
/>
<DiscussionItem
title="Native Invisibility"
author="Darrin Collins"
excerpt="Delves into the complex and often insidious ways in which indigenous peoples and their unique experiences are rendered unseen and unheard in the modern era."
/>
</>
);
}

export default DiscussionsTab;
130 changes: 130 additions & 0 deletions src/app/dashboard/admin/community-and-events/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"use client";
import { useRouter, useSearchParams, useParams } from "next/navigation";
import { Header } from "@/components/dashboard/header";
import { ArrowLeft } from "lucide-react";
import { COMMUNITIES } from "../utills/data";
import DiscussionsTab from "./components/DiscussionsTab";
import DiscussionSummary from "./components/DiscussionSummary";

type TabKey = "discussion" | "live" | "about" | "members";
const TABS: TabKey[] = ["discussion", "live", "about", "members"];

export default function Page() {
const router = useRouter();
const sp = useSearchParams();
const params = useParams<{ id: string }>();

const numericId = Number(params.id);
const community = COMMUNITIES.find((c) => c.id === numericId);

// tabs from ?tab=
const tabParam = (sp.get("tab") as TabKey) || "discussion";
const tab: TabKey = TABS.includes(tabParam) ? tabParam : "discussion";

const setTab = (next: TabKey) => {
const qp = new URLSearchParams(sp.toString());
if (next === "discussion") qp.delete("tab");
else qp.set("tab", next);
router.push(`?${qp.toString()}`);
};

if (!community) {
return (
<>
<Header title="Community and Events" />
<div className="p-6">
<button
onClick={() => router.back()}
className="mb-3 inline-flex items-center gap-2 text-[#3A3A3A]"
>
<ArrowLeft size={18} /> Back
</button>
<div className="bg-white p-6 rounded-[8px]">Community not found.</div>
</div>
</>
);
}

return (
<>
<Header title={`Community and Events / ${community.name}`} />
<div className="p-6">
<button
onClick={() => router.push("/dashboard/admin/community-and-events")}
className="mb-3 inline-flex items-center gap-2 text-[#3A3A3A]"
>
<ArrowLeft size={18} /> Back
</button>

<DiscussionSummary community={community} />

<div
className="mt-4 rounded-[8px] bg-white p-4"
style={{ boxShadow: "0px 6px 6px 0px #1212120A" }}
>
<div className="flex gap-2 items-center mb-6">
<button
onClick={() => setTab("discussion")}
className={`py-2 px-4 rounded-[8px] text-[#5D5D5D] ${
tab === "discussion" && " font-bold bg-[#F6F6F6]"
}`}
>
Discussion
</button>
<button
onClick={() => setTab("live")}
className={`py-2 px-4 rounded-[8px] text-[#5D5D5D] flex items-center gap-x-2 ${
tab === "live" && " font-bold bg-[#F6F6F6]"
}`}
>
Live
{community.liveNow && (
<span className="w-4 h-4 text-[11px] flex items-center justify-center bg-[#FF5C5C] text-white rounded-full">
1
</span>
)}
</button>
<button
onClick={() => setTab("about")}
className={`py-2 px-4 rounded-[8px] text-[#5D5D5D] ${
tab === "about" && " font-bold bg-[#F6F6F6]"
}`}
>
About
</button>
<button
onClick={() => setTab("members")}
className={`py-2 px-4 rounded-[8px] text-[#5D5D5D] ${
tab === "members" && " font-bold bg-[#F6F6F6]"
}`}
>
Members
</button>
</div>

<div className="flex flex-col gap-4">
{tab === "discussion" && <DiscussionsTab />}

{tab === "live" && (
<div className="text-[#555]">
{community.liveNow
? "A live session is currently running."
: "No live sessions right now."}
</div>
)}

{tab === "about" && (
<div className="text-[#444] leading-7">
{community.description}
</div>
)}

{tab === "members" && (
<div className="text-[#666]">Members list coming soon…</div>
)}
</div>
</div>
</div>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"use client";
import { useRouter, useSearchParams } from "next/navigation";

const FILTER_OPTIONS = [
{ key: "week", label: "This Week" },
{ key: "month", label: "This Month" },
{ key: "year", label: "This Year" },
{ key: "all", label: "All Time" },
];

function CommunityAndEventsFilter() {
const router = useRouter();
const searchParams = useSearchParams();

const activeFilter = searchParams.get("filter") || "week";
const start = searchParams.get("start") || "";
const end = searchParams.get("end") || "";

const pushWith = (next: Record<string, string | number | undefined>) => {
const params = new URLSearchParams(searchParams.toString());
Object.entries(next).forEach(([k, v]) => {
if (v === undefined || v === null || v === "") params.delete(k);
else params.set(k, String(v));
});
params.delete("page");
router.push(`?${params.toString()}`);
};

const onFilterClick = (key: string) => {
pushWith({ filter: key, start: undefined, end: undefined });
};

const onApplyDates = () => {
pushWith({ start, end, filter: undefined });
};

return (
<div className="flex justify-between items-center">
<div className="flex gap-x-2 items-center">
{FILTER_OPTIONS.map((opt) => (
<button
key={opt.key}
onClick={() => onFilterClick(opt.key)}
className={`px-2 py-[6px] rounded-[4px] ${
activeFilter === opt.key && !start && !end
? "bg-[#F6F6F6] text-[#454545]"
: "bg-transparent text-[#888888]"
}`}
>
{opt.label}
</button>
))}
</div>

<div className="flex gap-x-4 items-center">
<div className="flex gap-x-2 items-center">
<input
type="text"
placeholder="dd/mm/yyyy"
value={start}
onChange={(e) => pushWith({ start: e.target.value })}
className="w-[106px] py-[6px] px-3 border border-[#E7E7E7] rounded-[8px] outline-none"
/>
<span>to</span>
<input
type="text"
placeholder="dd/mm/yyyy"
value={end}
onChange={(e) => pushWith({ end: e.target.value })}
className="w-[106px] py-[6px] px-3 border border-[#E7E7E7] rounded-[8px] outline-none"
/>
</div>
<button
onClick={onApplyDates}
className="w-[60px] py-[6px] text-[#888888] bg-[#E7E7E7] rounded-[4px]"
>
Apply
</button>
</div>
</div>
);
}

export default CommunityAndEventsFilter;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from "react";

function CommunityStats() {
return (
<div className="p-4 grid grid-cols-4 gap-x-6 items-stretch border-[1px] border-[#E7E7E7] rounded-[8px]">
<div className="text-[#888888] py-3 px-6 border-[1px] border-[#E9F7FF] rounded-[8px]">
<h3 className="mb-2 text-sm/[100%]">Total Communities</h3>
<h2 className="text-base/[24px] font-bold">49</h2>
</div>
<div className="text-[#888888] py-3 px-6 border-[1px] border-[#E9F7FF] rounded-[8px]">
<h3 className="mb-2 text-sm/[100%]">Live Events</h3>
<h2 className="text-base/[24px] font-bold">4</h2>
</div>
<div className="text-[#888888] py-3 px-6 border-[1px] border-[#E9F7FF] rounded-[8px]">
<h3 className="mb-2 text-sm/[100%]">Public Communities</h3>
<h2 className="text-base/[24px] font-bold">32</h2>
</div>
<div className="text-[#888888] py-3 px-6 border-[1px] border-[#E9F7FF] rounded-[8px]">
<h3 className="mb-2 text-sm/[100%]">Private Communities</h3>
<h2 className="text-base/[24px] font-bold">18</h2>
</div>
</div>
);
}

export default CommunityStats;
Loading
Loading