Skip to content

Commit

Permalink
feat(ui): added filtering on the dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
dsebastien committed Oct 11, 2024
1 parent 34e3d07 commit 919b417
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 24 deletions.
17 changes: 3 additions & 14 deletions apps/knowii/src/Components/Communities/CommunityIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GrGroup } from 'react-icons/gr';
import { CommunityVisibility } from '@knowii/common';
import { CommunityVisibility, communityVisibilityOptions } from '@knowii/common';

interface Props {
visibility: CommunityVisibility | null;
Expand All @@ -9,19 +9,8 @@ const CommunityIcon = (props: Props) => {
let color = '';

if (props.visibility) {
switch (props.visibility) {
case 'public':
color = 'text-green-500';
break;
case 'private':
color = 'text-primary-500';
break;
case 'personal':
color = 'text-yellow-500';
break;
default:
color = '';
}
const matchedVisibility = communityVisibilityOptions.find((item) => item.visibility === props.visibility);
color = matchedVisibility ? matchedVisibility.color : '';
}

return <GrGroup className={color} />;
Expand Down
60 changes: 54 additions & 6 deletions apps/knowii/src/Pages/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import AppLayout from '@/Layouts/AppLayout';
import { useState } from 'react';
import { useCallback, useState } from 'react';
import CommunityBox from '@/Components/Communities/CommunityBox';
import { Community, COMMUNITY_URL, useTypedPage } from '@knowii/common';
import { Community, COMMUNITY_URL, communityVisibilityOptions } from '@knowii/common';
import CardGroup from '@/Components/CardGroup';
import { useImmer } from 'use-immer';
import { useRoute } from 'ziggy-js';
import CreateCommunityDialog from '@/Components/Communities/CreateCommunityDialog';
import { MenuItem } from 'primereact/menuitem';
import { FaHome } from 'react-icons/fa';
import { InputText } from 'primereact/inputtext';
import { Dropdown } from 'primereact/dropdown';
import { Button } from 'primereact/button';
import CommunityIcon from '@/Components/Communities/CommunityIcon';

export default function DashboardPage() {
const page = useTypedPage();
interface Props {
communities: Community[];
}

export default function DashboardPage(props: Props) {
const route = useRoute();

const breadcrumbItems: MenuItem[] = [
Expand All @@ -26,7 +33,9 @@ export default function DashboardPage() {
];

const [creatingCommunity, setCreatingCommunity] = useState(false);
const [communities, updateCommunities] = useImmer<Community[]>(page.props.communities);
const [communities, updateCommunities] = useImmer<Community[]>(props.communities);
const [searchTerm, setSearchTerm] = useState('');
const [visibilityFilter, setVisibilityFilter] = useState('');

const openCreateCommunityModal = () => {
setCreatingCommunity(true);
Expand All @@ -42,14 +51,53 @@ export default function DashboardPage() {
});
};

const filteredCommunities = useCallback(() => {
return communities.filter((community) => {
const matchesSearch =
community.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
community.description.toLowerCase().includes(searchTerm.toLowerCase());
const matchesVisibility = visibilityFilter ? community.visibility === visibilityFilter : true;
return matchesSearch && matchesVisibility;
});
}, [communities, searchTerm, visibilityFilter]);

const clearFilters = () => {
setSearchTerm('');
setVisibilityFilter('');
};

return (
<>
<AppLayout browserPageTitle="Dashboard" breadcrumbItems={breadcrumbItems}>
<h2 className="text-2xl font-bold mb-6 text-gray-800 border-b-2 border-primary-500 pb-2 block text-center sm:text-left">
My Communities
</h2>
<div className="flex flex-col sm:flex-row sm:justify-center md:justify-start gap-4 mb-4">
<InputText
placeholder="Search communities..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="p-inputtext-sm md:w-[34rem] lg:w-[48rem]"
/>
<Dropdown
options={communityVisibilityOptions}
optionLabel="name"
optionValue="visibility"
itemTemplate={(option) => (
<span className="text-sm flex items-center gap-2">
<CommunityIcon visibility={option.visibility} />
{option.name}
</span>
)}
value={visibilityFilter}
onChange={(e) => setVisibilityFilter(e.value)}
placeholder="Filter by visibility"
className="p-inputtext-sm"
/>
<Button severity="secondary" label="Clear Filters" onClick={clearFilters} className="p-button-sm" />
</div>
<CardGroup className="mt-4">
{communities.map((item) => (
{filteredCommunities().map((item) => (
<li className="w-full sm:w-auto" key={item.cuid}>
<CommunityBox
community={item}
Expand Down
8 changes: 4 additions & 4 deletions libs/common/src/lib/types/community.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ const communityVisibilitySchema = z.enum(['personal', 'private', 'public'], {
});
export type CommunityVisibility = z.infer<typeof communityVisibilitySchema>;

export const communityVisibilityOptions: Array<{ name: string; visibility: CommunityVisibility }> = [
{ name: 'Personal', visibility: 'personal' },
{ name: 'Private', visibility: 'private' },
{ name: 'Public', visibility: 'public' },
export const communityVisibilityOptions: Array<{ name: string; visibility: CommunityVisibility; color: string }> = [
{ name: 'Personal', visibility: 'personal', color: 'text-yellow-500' },
{ name: 'Private', visibility: 'private', color: 'text-primary-500' },
{ name: 'Public', visibility: 'public', color: 'text-green-500' },
];

export const newCommunitySchema = z.object({
Expand Down

0 comments on commit 919b417

Please sign in to comment.