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/application design #7

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion src/app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import styles from './app.module.scss';
import Login from './../pages/Login';
import Signup from './../pages/Signup';
import Channels from './../pages/Channels';

export function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/channels" element={<Channels />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
<Route path="*" element={<div>404</div>} />
Expand Down
9 changes: 9 additions & 0 deletions src/components/MemberStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface MemberStatusProps {
isConnected: boolean;
}

export default function MemberStatus({isConnected}: MemberStatusProps) {
return (
<div className={`px-2 py-1 rounded-xl ${isConnected ? 'bg-green-300' : 'bg-red-300'}`}><p className="font-semibold text-xs">{isConnected ? 'Online' : 'Offline'}</p></div>
);
}
17 changes: 17 additions & 0 deletions src/components/MembersListHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { LucideChevronDown } from "lucide-react";
import AddMembersButton from "./button/AddMembersButton";

interface MembersListHeaderProps {
}

export default function MembersListHeader(props: MembersListHeaderProps) {
return (
<div className="flex flex-row justify-between items-center gap-10">
<div className="flex flex-row gap-2">
<LucideChevronDown />
<h5 className="text-slate-900 font-semibold">Members</h5>
</div>
<AddMembersButton title="Add members" />
</div>
);
}
25 changes: 25 additions & 0 deletions src/components/MembersListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import MemberStatus from "./MemberStatus";
import { LucideMessageCircleMore } from "lucide-react";

interface MembersListItemProps {
name: string;
image: string;
isConnected: boolean;
}

export default function MembersListItem({name, image, isConnected}: MembersListItemProps) {
return (
<div className="flex flex-row justify-between items-center p-2 hover:bg-violet-400 rounded-xl transition-all cursor-pointer w-full group">
<div className="flex flex-row gap-3 items-center">
<img className="w-9 min-w-[36px] h-9 min-h-[36px] bg-violet-50 rounded-xl" src={image} alt={name + "-img"} />
<h5 className="font-semibold text-xs truncate w-[125px]">{name}</h5>
</div>
<div className="flex flex-row gap-3 items-center">
<MemberStatus isConnected={isConnected} />
<button className="hidden group-hover:block">
<LucideMessageCircleMore className="w-[20px] h-[20px]"/>
</button>
</div>
</div>
);
}
14 changes: 14 additions & 0 deletions src/components/MessagesHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { LucideHash, LucideChevronDown } from "lucide-react";

interface MessagesHeaderProps {
channel: string;
}

export default function MessagesHeader({channel}: MessagesHeaderProps) {
return (
<div className="flex flex-row justify-between">
<div className="flex flex-row gap-2 items-center justify-center p-4 bg-violet-300 rounded-xl"><LucideHash className="w-4 h-4"/><h5 className="font-semibold">{channel}</h5></div>
<button className="flex flex-row gap-2 items-center justify-center p-4 bg-violet-300 rounded-xl"><h5 className="font-semibold">📌 Pinned messages</h5><LucideChevronDown className="w-4 h-4"/></button>
</div>
);
}
11 changes: 11 additions & 0 deletions src/components/button/AddMembersButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { LucidePlus } from "lucide-react";

interface AddMembersButtonProps {
title : string;
}

export default function AuthButton({title}: AddMembersButtonProps) {
return (
<button className='bg-violet-400 px-3 py-2 text-base w-full rounded-xl hover:rounded-2xl transition-rounded font-semibold flex flex-row'><LucidePlus/>{title}</button>
);
};
16 changes: 16 additions & 0 deletions src/components/button/IconButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
interface IconButtonProps {
onClick: () => void;
children?: React.ReactNode;
className?: string;
}

export default function IconButton({onClick, children, className}: IconButtonProps) {
return (
<button
className={`w-[50px] min-w-[50px] h-[50px] min-h-[50px] bg-violet-50 flex justify-center items-center text-slate-900 hover:bg-violet-100 rounded-xl hover:rounded-2xl transition-all ${className}`}
onClick={onClick}
>
{children}
</button>
);
}
9 changes: 9 additions & 0 deletions src/components/input/MessageInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface MessageInputProps {
}

export default function MessageInput(props: MessageInputProps) {
return (
<input className="rounded-xl bg-violet-50 px-4" placeholder="Type a message">
</input>
);
}
132 changes: 132 additions & 0 deletions src/pages/Channels.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import MembersListItem from "../components/MembersListItem";
import MembersListHeader from "../components/MembersListHeader";
import IconButton from "../components/button/IconButton";
import { LucideMail, LucidePlus, LucideLogOut, LucideSend } from "lucide-react";
import MessagesHeader from "../components/MessagesHeader";
import MessageInput from "../components/input/MessageInput";

interface ChannelsProps {
}

const channels = [
{
id: 1,
name: "general",
description: "general discussion",
},
{
id: 2,
name: "random",
description: "random discussion",
},
{
id: 3,
name: "random",
description: "random discussion",
},
{
id: 4,
name: "random",
description: "random discussion",
},
{
id: 5,
name: "random",
description: "random discussion",
},
{
id: 6,
name: "random",
description: "random discussion",
},
{
id: 7,
name: "random",
description: "random discussion",
},
];

const members = [
{
id: 1,
name: "John Doe",
isConnected: true,
image: ""
},
{
id: 2,
name: "John Doe",
isConnected: false,
image: ""
},
{
id: 3,
name: "John Doe",
isConnected: true,
image: ""
},
{
id: 4,
name: "John Doe",
isConnected: true,
image: ""
}
];

const actualChannel = {
id: 1,
name: "General",
description: "general discussion",
};

export default function Channels(props: ChannelsProps) {
return (
<div className="flex flex-row bg-violet-500">
<div className="bg-violet-200 p-6">
<MessagesHeader channel={actualChannel.name} />
<div className="flex flex-col gap-3 font-medium">
<p>Rapidement is typing...</p>
<div className="flex flex-row gap-6">
<MessageInput />
<IconButton onClick={() => {}}>
<LucideSend />
</IconButton>
<IconButton onClick={() => {}}>
<LucidePlus />
</IconButton>
</div>
</div>
</div>

<div className="bg-violet-300 p-6 rounded-r-3xl flex flex-col gap-2">
<MembersListHeader />
<div className="flex flex-col gap-1">
{members.map((member) => (
<MembersListItem key={member.id} name={member.name} isConnected={member.isConnected} image={member.image}/>
))}
</div>
</div>

<div className="bg-violet-500 flex flex-col w-min h-screen p-6 ">
<div className="pb-12">
<IconButton onClick={() => {}}>
<LucideMail />
</IconButton>
</div>
<div className="flex flex-col gap-6 flex-grow overflow-y-scroll no-scrollbar scroll-smooth">
{channels.map((channel) => (
<IconButton key={channel.id} onClick={() => {}} />
))}
<IconButton onClick={() => {}}>
<LucidePlus />
</IconButton>
</div>
<div className="pt-12">
<IconButton onClick={() => {}}>
<LucideLogOut />
</IconButton>
</div>
</div>
</div>
);
}
14 changes: 14 additions & 0 deletions src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,18 @@
h5 {
@apply text-base;
}
p {
@apply text-sm;
}
}

@layer utilities {
.no-scrollbar::-webkit-scrollbar {
display: none;
}

.no-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
}
3 changes: 3 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ module.exports = {
backgroundImage: {
cloud: 'url("/src/assets/background.svg")',
},
transitionProperty: {
'rounded': 'border-radius',
},
},
},
plugins: [],
Expand Down