Skip to content

Commit 3b95354

Browse files
committed
End frontDs
1 parent bed627f commit 3b95354

28 files changed

+1335
-24
lines changed

package-lock.json

+672
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,18 @@
1010
"preview": "vite preview"
1111
},
1212
"dependencies": {
13+
"@radix-ui/react-accordion": "^1.1.2",
1314
"@radix-ui/react-avatar": "^1.0.4",
15+
"@radix-ui/react-popover": "^1.0.7",
16+
"@radix-ui/react-slot": "^1.0.2",
1417
"class-variance-authority": "^0.7.0",
1518
"clsx": "^2.1.1",
19+
"emoji-picker-react": "^4.9.4",
1620
"lucide": "^0.390.0",
1721
"lucide-react": "^0.390.0",
1822
"react": "^18.2.0",
1923
"react-dom": "^18.2.0",
24+
"react-router-dom": "^6.23.1",
2025
"tailwind-merge": "^2.3.0",
2126
"tailwindcss-animate": "^1.0.7"
2227
},
@@ -32,6 +37,7 @@
3237
"eslint-plugin-react-hooks": "^4.6.0",
3338
"eslint-plugin-react-refresh": "^0.4.6",
3439
"postcss": "^8.4.38",
40+
"tailwind-scrollbar": "^3.1.0",
3541
"tailwindcss": "^3.4.4",
3642
"typescript": "^5.2.2",
3743
"vite": "^5.2.0"

public/assets/avatar.avif

6.52 KB
Binary file not shown.

public/assets/login.png

73.3 KB
Loading
File renamed without changes.

src/App.tsx

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import Chat from "./components/chat"
2-
import Details from "./components/details"
3-
import List from "./components/list"
4-
import { Card } from "./components/ui/card"
1+
import { BrowserRouter, Route, Routes } from "react-router-dom"
2+
import Home from "./components/Home"
3+
import Login from "./components/login"
54

65

76

87
function App() {
98

109
return (
11-
<main className='w-full h-[100vh] overflow-hidden flex items-center justify-center bg-white'>
12-
<Card className="w-4/5 h-[90%] flex rounded-xl overflow-hidden">
13-
<List />
14-
<Chat />
15-
<Details />
16-
</Card>
17-
</main>
10+
<div className="w-full h-[100vh] flex items-center justify-center">
11+
<BrowserRouter>
12+
<Routes>
13+
<Route path="/" element={<Home />} />
14+
<Route path="/login" element={<Login />} />
15+
</Routes>
16+
</BrowserRouter>
17+
</div>
1818
)
1919
}
2020

src/components/Home.tsx

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Card } from "./ui/card";
2+
import Chat from "./chat";
3+
import Details from "./details";
4+
import List from "./list";
5+
6+
const Home = () => {
7+
return (
8+
<Card className="w-4/5 h-[90%] flex rounded-xl overflow-hidden">
9+
<List />
10+
<Chat />
11+
<Details />
12+
</Card>
13+
);
14+
};
15+
16+
export default Home;

src/components/MyAccordion.tsx

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { AccordionProps } from "@/types"
2+
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./ui/accordion"
3+
import { cn } from "@/lib/utils"
4+
5+
6+
const MyAccordion = ({children, title, contentClassName, triggerClassName}: AccordionProps) => {
7+
return (
8+
<Accordion
9+
type="single"
10+
collapsible
11+
className="w-full bg-transparent"
12+
>
13+
<AccordionItem
14+
value="item-1"
15+
className="border-none"
16+
>
17+
<AccordionTrigger className={cn("font-bold hover:no-underline", triggerClassName)}>
18+
{title}
19+
</AccordionTrigger>
20+
<AccordionContent className={cn(contentClassName)}>
21+
{children}
22+
</AccordionContent>
23+
</AccordionItem>
24+
</Accordion>
25+
)
26+
}
27+
28+
export default MyAccordion

src/components/MyPopOver.tsx

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { PopoverProps } from "@/types";
2+
3+
import { cn } from "@/lib/utils";
4+
import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover";
5+
import { Button } from "./ui/button";
6+
7+
8+
const MyPopOver = ({
9+
buttonOver,
10+
children,
11+
buttonClassName,
12+
popOverClassName,
13+
}: PopoverProps) => {
14+
return (
15+
<Popover>
16+
<PopoverTrigger>
17+
<Button className={cn(buttonClassName, "bg-transparent text-secondary-foreground px-0 hover:bg-transparent")}>
18+
{buttonOver}
19+
</Button>
20+
</PopoverTrigger>
21+
<PopoverContent className={cn(popOverClassName, "p-4")}>
22+
{ children }
23+
</PopoverContent>
24+
</Popover>
25+
)
26+
}
27+
28+
export default MyPopOver

src/components/chat/ChatContent.tsx

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { Avatar, AvatarImage } from "../ui/avatar";
2+
import { Card } from "../ui/card";
3+
4+
const ChatContent = () => {
5+
return (
6+
<div className="flex-1 p-4 overflow-y-auto flex flex-col gap-2 scrollbar-thin scrollbar-thumb-current">
7+
<div className="flex gap-2 items-start">
8+
<Avatar className="w-6 h-6">
9+
<AvatarImage src="https://img.freepik.com/free-psd/3d-illustration-human-avatar-profile_23-2150671142.jpg?size=338&ext=jpg&ga=GA1.1.1141335507.1717804800&semt=ais_user" />
10+
</Avatar>
11+
<Card className="max-w-[70%] px-2 py-1 bg-secondary flex gap-2 items-end relative">
12+
<p className="flex flex-wrap py-1"> Lorem ipsum dolor sit amet. </p>
13+
<span className="text-xs"> 11:00 </span>
14+
</Card>
15+
</div>
16+
<div className="flex gap-2 items-start justify-end">
17+
<Card className="max-w-[70%] px-2 py-1 bg-primary text-foreground flex gap-2 items-end relative">
18+
<p className="flex flex-wrap py-1"> Lorem ipsum dolor sit amet. </p>
19+
<span className="text-xs"> 11:00 </span>
20+
</Card>
21+
<Avatar className="w-6 h-6">
22+
<AvatarImage src="https://img.freepik.com/free-psd/3d-illustration-human-avatar-profile_23-2150671142.jpg?size=338&ext=jpg&ga=GA1.1.1141335507.1717804800&semt=ais_user" />
23+
</Avatar>
24+
</div>
25+
<div className="flex gap-2 items-start justify-end">
26+
<div className="max-w-[70%] px-2 py-1 text-foreground flex gap-2 items-end relative">
27+
<img
28+
src="https://img.ibxk.com.br/2024/01/17/17113534532068.jpg?ims=328x"
29+
className="w-full h-[250px] object-cover rounded-lg"
30+
/>
31+
</div>
32+
<Avatar className="w-6 h-6">
33+
<AvatarImage src="https://img.freepik.com/free-psd/3d-illustration-human-avatar-profile_23-2150671142.jpg?size=338&ext=jpg&ga=GA1.1.1141335507.1717804800&semt=ais_user" />
34+
</Avatar>
35+
</div>
36+
<div className="flex gap-2 items-start">
37+
<Avatar className="w-6 h-6">
38+
<AvatarImage src="https://img.freepik.com/free-psd/3d-illustration-human-avatar-profile_23-2150671142.jpg?size=338&ext=jpg&ga=GA1.1.1141335507.1717804800&semt=ais_user" />
39+
</Avatar>
40+
<Card className="max-w-[70%] px-2 py-1 bg-secondary flex gap-2 items-end relative">
41+
<p className="flex flex-wrap py-1"> Lorem ipsum dolor sit amet. </p>
42+
<span className="text-xs"> 11:00 </span>
43+
</Card>
44+
</div>
45+
<div className="flex gap-2 items-start">
46+
<Avatar className="w-6 h-6">
47+
<AvatarImage src="https://img.freepik.com/free-psd/3d-illustration-human-avatar-profile_23-2150671142.jpg?size=338&ext=jpg&ga=GA1.1.1141335507.1717804800&semt=ais_user" />
48+
</Avatar>
49+
<Card className="max-w-[70%] px-2 py-1 bg-secondary flex gap-2 items-end relative">
50+
<p className="flex flex-wrap py-1"> Lorem ipsum dolor sit amet. </p>
51+
<span className="text-xs"> 11:00 </span>
52+
</Card>
53+
</div>
54+
<div className="flex gap-2 items-start">
55+
<Avatar className="w-6 h-6">
56+
<AvatarImage src="https://img.freepik.com/free-psd/3d-illustration-human-avatar-profile_23-2150671142.jpg?size=338&ext=jpg&ga=GA1.1.1141335507.1717804800&semt=ais_user" />
57+
</Avatar>
58+
<div className="max-w-[70%] px-2 py-1 text-foreground flex gap-2 items-end relative">
59+
<img
60+
src="https://img.ibxk.com.br/2024/01/17/17113534532068.jpg?ims=328x"
61+
className="w-full h-[250px] object-cover rounded-lg"
62+
/>
63+
</div>
64+
</div>
65+
</div>
66+
);
67+
};
68+
69+
export default ChatContent;

src/components/chat/FooterChat.tsx

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { Mic, SendHorizonal, Smile } from "lucide-react";
2+
import { Card } from "../ui/card";
3+
import { Input } from "../ui/input";
4+
import { Button } from "../ui/button";
5+
import EmojiPicker, { EmojiClickData } from "emoji-picker-react";
6+
import { useState } from "react";
7+
import PickerFile from "./PickerFile";
8+
9+
const FooterChat = () => {
10+
const [message, setMessage] = useState("");
11+
const [openEmojiePicker, setOpenEmojiePicker] = useState(false);
12+
13+
const handleEmojiePicker = (e: EmojiClickData) => {
14+
setMessage((prev) => prev + e.emoji);
15+
setOpenEmojiePicker(false);
16+
};
17+
18+
return (
19+
<Card className="flex gap-2 items-center p-2 mx-4 mb-4">
20+
<div className="relative">
21+
<Smile
22+
size={20}
23+
className="cursor-pointer"
24+
onClick={() => setOpenEmojiePicker((prevState) => !prevState)}
25+
/>
26+
<div className="absolute left-0 bottom-10">
27+
<EmojiPicker
28+
open={openEmojiePicker}
29+
onEmojiClick={handleEmojiePicker}
30+
/>
31+
</div>
32+
</div>
33+
<Input
34+
value={message}
35+
onChange={(e) => setMessage(e.target.value)}
36+
placeholder="type message"
37+
className="bg-transparent border-none flex-1 px-0"
38+
/>
39+
<PickerFile />
40+
<Mic size={20} className="cursor-pointer" />
41+
<Button className="p-2 bg-primary">
42+
<SendHorizonal size={20} className="cursor-pointer" />
43+
</Button>
44+
</Card>
45+
);
46+
};
47+
48+
export default FooterChat;

src/components/chat/HearderChat.tsx

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
1+
import { Ellipsis, Phone, Video } from "lucide-react"
2+
import { Avatar, AvatarImage } from "../ui/avatar"
13

24

35
const HearderChat = () => {
46
return (
5-
<div>HearderChat</div>
7+
<div className="w-full p-4 flex items-center justify-between border-b border-secondary">
8+
<div className="flex items-center gap-2 cursor-pointer">
9+
<Avatar>
10+
<AvatarImage src="https://img.freepik.com/free-psd/3d-illustration-human-avatar-profile_23-2150671142.jpg?size=338&ext=jpg&ga=GA1.1.1141335507.1717804800&semt=ais_user" />
11+
</Avatar>
12+
<span className="font-semibold"> John Doe </span>
13+
</div>
14+
15+
<div className="flex items-center justify-center gap-6">
16+
<Phone className="cursor-pointer hover:text-primary" />
17+
<Video className="cursor-pointer hover:text-primary" />
18+
<Ellipsis className="cursor-pointer hover:text-primary" />
19+
</div>
20+
</div>
621
)
722
}
823

src/components/chat/PickerFile.tsx

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Camera, FileText, Headphones, Images, Paperclip } from "lucide-react";
2+
import MyPopOver from "../MyPopOver";
3+
4+
const PickerFile = () => {
5+
return (
6+
<MyPopOver
7+
popOverClassName="grid grid-cols-2 gap-2 items-center justify-center max-w-40 bg-popover"
8+
buttonOver={<Paperclip
9+
size={20}
10+
className="cursor-pointer"
11+
/>}
12+
>
13+
<div className="py-4 rounded-full bg-primary text-white flex items-center justify-center">
14+
<Camera size={25} />
15+
</div>
16+
<div className="py-4 rounded-full bg-primary text-white flex items-center justify-center">
17+
<Images size={25} />
18+
</div>
19+
<div className="py-4 rounded-full bg-primary text-white flex items-center justify-center">
20+
<FileText size={25} />
21+
</div>
22+
<div className="py-4 rounded-full bg-primary text-white flex items-center justify-center">
23+
<Headphones size={25} />
24+
</div>
25+
</MyPopOver>
26+
);
27+
};
28+
29+
export default PickerFile;

src/components/chat/index.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
import ChatContent from "./ChatContent"
2+
import FooterChat from "./FooterChat"
13
import HearderChat from "./HearderChat"
24

35

46
const Chat = () => {
57
return (
6-
<div className="flex-[2] bg-foreground">
8+
<div className="relative flex-[2] bg-foreground flex flex-col max-h-[100%]">
79
<HearderChat />
8-
Chat
10+
<ChatContent />
11+
<FooterChat />
912
</div>
1013
)
1114
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import MyAccordion from "../MyAccordion";
2+
3+
const ChatSettings = () => {
4+
return (
5+
<MyAccordion title="Chat Settings">
6+
<p>Chat Settings</p>
7+
</MyAccordion>
8+
);
9+
};
10+
11+
export default ChatSettings;
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Avatar, AvatarImage } from "../ui/avatar"
2+
3+
4+
const HeaderDetails = () => {
5+
return (
6+
<div className="w-full flex flex-col gap-4 items-center justify-center px-4 pb-4 border-b border-foreground">
7+
<Avatar className="w-24 h-24">
8+
<AvatarImage src="https://img.freepik.com/free-psd/3d-illustration-human-avatar-profile_23-2150671142.jpg?size=338&ext=jpg&ga=GA1.1.1141335507.1717804800&semt=ais_user" />
9+
</Avatar>
10+
<div className="flex flex-col items-center">
11+
<span className="font-bold"> Cristooo Jr </span>
12+
<span className="text-sm font-extralight"> Lorem ipsum dolor sit amet. </span>
13+
</div>
14+
</div>
15+
)
16+
}
17+
18+
export default HeaderDetails
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import MyAccordion from "../MyAccordion";
2+
3+
const SharedFiles = () => {
4+
return (
5+
<MyAccordion title="Shared Files">
6+
<p>Shared Files</p>
7+
</MyAccordion>
8+
);
9+
};
10+
11+
export default SharedFiles;
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import MyAccordion from "../MyAccordion"
2+
3+
4+
const SharedPhotos = () => {
5+
return (
6+
<MyAccordion title="Shared Photos">
7+
<p>Shared photos</p>
8+
</MyAccordion>
9+
)
10+
}
11+
12+
export default SharedPhotos

0 commit comments

Comments
 (0)