Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fix member management functionality issue #211

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9c8c882
updated
pauluwaifo Jul 20, 2024
7a9f492
feat: fix member manegement functionality issue
pauluwaifo Jul 20, 2024
3a5e40e
use pnpm in deploy scripts
ickynavigator Jul 20, 2024
c88f5e0
feat: fix member management function-on admin dashboard
pauluwaifo Jul 20, 2024
e8947c0
ran update
pauluwaifo Jul 21, 2024
d258982
Merge branch 'dev' of https://github.com/hngprojects/hng_boilerplate_…
pauluwaifo Jul 21, 2024
204cf1e
Merge branch 'dev' of https://github.com/hngprojects/hng_boilerplate_…
pauluwaifo Jul 21, 2024
626578f
Merge branch 'dev' of https://github.com/hngprojects/hng_boilerplate_…
pauluwaifo Jul 21, 2024
6a405a6
updated
pauluwaifo Jul 21, 2024
e378327
updated my code
pauluwaifo Jul 21, 2024
5458126
updated
pauluwaifo Jul 21, 2024
9662428
feat: fix Member Management Functionalities on Admin Dashboard
pauluwaifo Jul 21, 2024
dec96ed
feat: fix user search filter issue
pauluwaifo Jul 21, 2024
521125f
pulled from upstream and updated
pauluwaifo Jul 22, 2024
96969da
feat: fix pulled from upstream and fix filter issue
pauluwaifo Jul 22, 2024
fa3e2a9
feat: fix package.json issue
pauluwaifo Jul 22, 2024
e14d1cb
Merge branch 'dev' of https://github.com/hngprojects/hng_boilerplate_…
pauluwaifo Jul 22, 2024
ec7e5e1
Merge branch 'dev' into feat/HNG-77-Implement-Member-Management-Funct…
pauluwaifo Jul 22, 2024
9974f74
feat: Removed pnpm package from package.json
lordfrantex Jul 19, 2024
32d2df7
Merge branch 'feat/HNG-77-Implement-Member-Management-Functionalities…
pauluwaifo Jul 22, 2024
c6e7acb
passed lint test
lordfrantex Jul 20, 2024
94c2c8c
Merge pull request #385 from pauluwaifo/feat/HNG-77-Implement-Member-…
pauluwaifo Jul 23, 2024
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
168 changes: 168 additions & 0 deletions app/components/MemberManagement.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import { Link } from "@remix-run/react";
import { Angle_down, Arrow_right } from "~/components/ui/svgs";
import { useState, ChangeEvent } from "react";
import { Search, Check } from "lucide-react";

function MemberManagement() {
const [search, setSearch] = useState<string>("");
const [filter, setFilter] = useState<string>("All");
const [display, setDisplay] = useState<string>("none");
const handleSearch = (e: ChangeEvent<HTMLInputElement>) => {
setSearch(e.target.value);
};

// account type btn
const accountType_btn: string[] = [
"All",
"Members",
"Suspended",
"Left workspace",
];

interface User {
Copy link
Contributor

@chumex412 chumex412 Jul 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is bad code, please move these static data to another file and import it into this file.

id: number;
name: string;
email: string;
isAdmin: boolean;
isUser: boolean;
isGuest: boolean;
}

const users: User[] = [
{
id: 1,
name: "john doe",
email: "[email protected]",
isAdmin: true,
isUser: false,
isGuest: false,
},
{
id: 2,
name: "tester",
email: "[email protected]",
isAdmin: false,
isUser: true,
isGuest: false,
},
{
id: 3,
name: "rest2",
email: "[email protected]",
isAdmin: false,
isUser: true,
isGuest: false,
},
];

const userList = () => {
return (
<>
<p>{users.length} active members</p>
{users
.filter(
(user) =>
user.name.toLowerCase().includes(search.toLowerCase()) ||
user.email.toLowerCase().includes(search.toLowerCase())
)
.map((user) => (
<div key={user.id}>
<p>
{user.name}:{" "}
{user.isAdmin ? "Admin" : user.isGuest ? "Guest" : "Users"}
</p>
</div>
))}
</>
);
};

return (
<div className="flex flex-col flex-wrap p-5">
<p className="font-semibold text-lg">Manage members</p>

{/* heading */}
<div className="flex items-center flex-wrap text-sm">
On the Free plan all members in a workspace are administrators. Upgrade
to a paid plan to add the ability to assign or remove administrator
roles.
<Link
className="text-[#eb7300] flex flex-row items-center mx-1"
to={"/"}
>
Go to Plans
<span className="mx-2 fill-[#eb7300]">
<Arrow_right width={"12px"} />
</span>
</Link>
</div>

{/* search bar and invite button */}
<div className="flex flex-row flex-wrap mt-5 items-center">
<div className="flex flex-row basis-1/2">
<form
className="w-72 border-[1.5px] rounded-lg border-[#cdd5e1] px-2 flex flex-row items-center"
action=""
>
<span>
<Search width={"22px"} stroke="#525252" />
</span>
<input
type="text"
name="search"
id="search"
onChange={handleSearch}
placeholder="Search by name or email"
className="text-sm p-2 placeholder-[#525252] outline-none border-none basis-full"
/>
</form>
{/* drop down */}
<div className="flex relative">
{/* activate drop_down */}
<button
onClick={() => setDisplay("account_type")}
className="flex flex-row items-center justify-center border-[1.5px] rounded-lg border-[#cdd5e1] px-2 mx-2 overflow-hidden"
>
{filter}
<span className="ml-2 stroke-[#525252] stroke-[.2px]">
<Angle_down width={"20px"} />
</span>
</button>

{/* drop down content */}
<div
className={`absolute ${
display == "account_type" ? "flex" : "hidden"
} flex-col items-start bg-white top-0 left-2 shadow-[2px_1px_10px_2px_rgba(0,0,0,0.1)] p-2 w-64 rounded-sm text-[#525252] font-semibold flex-wrap`}
>
{accountType_btn.map((btn) => (
<button
className={`${
filter == btn && "bg-[#cdd5e1]"
} px-2 py-1 hover:bg-[#cdd5e1] w-full flex justify-between rounded transition ease-in-out delay-100`}
onClick={() => {
setFilter(btn), setDisplay("none");
}}
>
{btn}
{filter == btn && <Check />}
</button>
))}
</div>
</div>
</div>

<div className="flex flex-row basis-1/2 items-center justify-end">
<button className="bg-[#eb7300] text-white rounded-sm py-2 px-3">
Invite people
</button>
</div>
</div>


{userList()}
</div>
);
}

export default MemberManagement;
39 changes: 39 additions & 0 deletions app/components/ui/svgs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from "react";

interface Props {
width: string;
}

export const Arrow_right: React.FC<Props> = ({ width }) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width={width}>
<path d="M502.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L402.7 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l370.7 0-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l128-128z" />
</svg>
);
};

export const Search: React.FC<Props> = ({ width }) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
width={width}
>
<path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z" />
</svg>
);
};

export const Angle_down: React.FC<Props> = ({ width }) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
id="Outline"
viewBox="0 0 24 24"
width={width}
height="auto"
>
<path d="M18.71,8.21a1,1,0,0,0-1.42,0l-4.58,4.58a1,1,0,0,1-1.42,0L6.71,8.21a1,1,0,0,0-1.42,0,1,1,0,0,0,0,1.41l4.59,4.59a3,3,0,0,0,4.24,0l4.59-4.59A1,1,0,0,0,18.71,8.21Z" />
</svg>
);
};
38 changes: 2 additions & 36 deletions app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { MetaFunction } from "@remix-run/node";
import { Button } from "~/components/ui/button";
import MemberManagement from "~/components/MemberManagement";

export const meta: MetaFunction = () => {
return [
Expand All @@ -10,41 +11,6 @@ export const meta: MetaFunction = () => {

export default function Index() {
return (
<div className="font-sans p-4">
<h1 className="text-3xl">Welcome to Remix</h1>
<ul className="list-disc mt-4 pl-6 space-y-2">
<li>
<a
className="text-blue-700 underline visited:text-purple-900"
target="_blank"
href="https://remix.run/start/quickstart"
rel="noreferrer"
>
5m Quick Start
</a>
</li>
<li>
<a
className="text-blue-700 underline visited:text-purple-900"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does making changes to this file relate to this file?

target="_blank"
href="https://remix.run/start/tutorial"
rel="noreferrer"
>
30m Tutorial
</a>
</li>
<Button>Hello</Button>
<li>
<a
className="text-blue-700 underline visited:text-purple-900"
target="_blank"
href="https://remix.run/docs"
rel="noreferrer"
>
Remix Docs
</a>
</li>
</ul>
</div>
<MemberManagement />
);
}