From dd27de024f7d869bada44b977dd360a99b7fd49e Mon Sep 17 00:00:00 2001 From: Mohamed Jarboua Date: Tue, 12 Mar 2024 16:40:26 +0000 Subject: [PATCH 01/32] added something related to the modular toggle --- app/Dashboard/Chat/page.tsx | 8 +-- app/Dashboard/Chat/type.tsx | 4 ++ app/components/Dashboard/Chat/JoinChannel.tsx | 41 ++++++++++-- .../Dashboard/Chat/JoinChannelBubble.tsx | 67 +++++++++++++++---- app/globals.css | 27 ++++++++ 5 files changed, 123 insertions(+), 24 deletions(-) diff --git a/app/Dashboard/Chat/page.tsx b/app/Dashboard/Chat/page.tsx index 93f4d8b..422ea7f 100644 --- a/app/Dashboard/Chat/page.tsx +++ b/app/Dashboard/Chat/page.tsx @@ -3,13 +3,8 @@ import { ChatCard } from "@/app/components/Dashboard/Chat/ChatCard"; import MiddleBuble from "@/app/components/Dashboard/Chat/LeftBubbles/MiddleBuble"; import { AnimatePresence } from "framer-motion"; import { Inter } from "next/font/google"; -import { LuPhone } from "react-icons/lu"; -import { IoVideocamOutline } from "react-icons/io5"; import { IoIosInformationCircleOutline } from "react-icons/io"; import { CiCirclePlus } from "react-icons/ci"; -import { MdOutlineAddPhotoAlternate } from "react-icons/md"; -import { IoCameraOutline } from "react-icons/io5"; -import { PiMicrophoneLight } from "react-icons/pi"; import { IoSendOutline } from "react-icons/io5"; import { FormEvent, @@ -24,7 +19,6 @@ import { useGlobalState } from "@/app/components/Sign/GlobalState"; import { channel, target, user } from "./type"; import MiddleBubbleRight from "@/app/components/Dashboard/Chat/RightBubbles/MiddleBubbleRight"; import { useForm } from "react-hook-form"; -import { sendError } from "next/dist/server/api-utils"; import JoinChannel from "@/app/components/Dashboard/Chat/JoinChannel"; const inter = Inter({ subsets: ["latin"] }); @@ -254,7 +248,7 @@ const Page = () => { return (
- {modlar && } + {modlar && }
void }) => { + + +const JoinChannel = ({ handleClick, user }: { handleClick: () => void, user: user }) => { + const [channels, setChannels] = useState([]); + const [filteredChannels, setFilteredChannels] = useState([]); + const search = useRef(null); + const { register } = useForm(); + useEffect(() => { + const fetchChannels = async () => { + const res = await axios.get("http://localhost:8080/channels").then((data) => { + setChannels(data.data); + setFilteredChannels(data.data); + }); + }; + fetchChannels(); + }, []); + + const filterBySearch = (e: React.ChangeEvent, value: string | null) => { + const res = channels.filter((channel) => { + return channel.name.toLowerCase().includes(value?.toLowerCase() as string); + }); + setFilteredChannels(res); + }; + return (
- {Array.from({ length: 20 }, (_, index) => ( - - ))} + {filteredChannels.map((channel, key) => { + return ; + })}
handleClick()} /> diff --git a/app/components/Dashboard/Chat/JoinChannelBubble.tsx b/app/components/Dashboard/Chat/JoinChannelBubble.tsx index 7b9fef8..960a231 100644 --- a/app/components/Dashboard/Chat/JoinChannelBubble.tsx +++ b/app/components/Dashboard/Chat/JoinChannelBubble.tsx @@ -1,17 +1,60 @@ -import React from 'react' +import { channel, user } from "@/app/Dashboard/Chat/type"; +import React, { useState } from "react"; import { GoLock } from "react-icons/go"; -const JoinChannelBubble = ({lock}:{lock:boolean}) => { +interface TooltipProps { + content: string; + children: React.ReactNode; + // Add more props as needed for customization +} + +// const Tooltip: React.FC = ({ content, children }) => { +// return ( +//
+// {children} +//
+// ); +// }; + +const JoinChannelBubble = ({ + lock, + channel, + user, +}: { + lock: boolean; + channel: channel; + user: user; +}) => { + const [hover, setHover] = useState(false); + return ( -
- image -
-

JOIN US NOW

-

a fun interactive group of people

-
- {lock && } +
+ image +
setHover(true)} + onMouseLeave={(e) => setHover(false)} + title={channel.topic} + > +

+ {channel.name} +

+ {/* */} +

+ {channel.topic.substring(0, 30) + + (channel.topic.length > 30 && " ...")} +

+ {/*
*/} +
+ {lock && ( + + )}
- ) -} + ); +}; -export default JoinChannelBubble \ No newline at end of file +export default JoinChannelBubble; diff --git a/app/globals.css b/app/globals.css index e8ff2d5..00d40b5 100644 --- a/app/globals.css +++ b/app/globals.css @@ -229,3 +229,30 @@ tbody:before { .no-visible-scrollbar::-webkit-scrollbar { display: none; } + +.tooltip-container { + position: relative; + display: inline-block; +} + +.tooltip-container::after { + content: attr(title); + position: absolute; + bottom: 100%; + left: 50%; + z-index: 0; + transform: translateX(-50%); + background: #333; + color: #fff; + padding: 5px; + border-radius: 5px; + white-space: nowrap; + visibility: hidden; + opacity: 0; + transition: opacity 0.3s; +} + +.tooltip-container:hover::after { + visibility: visible; + opacity: 1; +} \ No newline at end of file From 1af1dd6dc2b45c26ccd254a000de3e243e6d3fac Mon Sep 17 00:00:00 2001 From: ybenlafk Date: Wed, 13 Mar 2024 14:49:53 +0000 Subject: [PATCH 02/32] change colors and fix profile page --- .../Dashboard/Profile/LinkedFriend.tsx | 42 +++++ .../Dashboard/Profile/UserProfile.tsx | 177 +++++++++++++----- .../Dashboard/Profile/Userstatus.tsx | 63 ++----- app/components/Dashboard/Search/UserCard.tsx | 17 +- .../Dashboard/Settings/EditProfile.tsx | 43 +++-- .../Dashboard/Settings/Security.tsx | 72 +++---- app/components/Dashboard/Settings/otp.tsx | 3 +- app/components/Dashboard/Sidebar/Option.tsx | 2 +- 8 files changed, 243 insertions(+), 176 deletions(-) create mode 100644 app/components/Dashboard/Profile/LinkedFriend.tsx diff --git a/app/components/Dashboard/Profile/LinkedFriend.tsx b/app/components/Dashboard/Profile/LinkedFriend.tsx new file mode 100644 index 0000000..d34ab75 --- /dev/null +++ b/app/components/Dashboard/Profile/LinkedFriend.tsx @@ -0,0 +1,42 @@ +import Image from 'next/image' +import React from 'react' +import { useRouter } from 'next/navigation' +import { Inter } from 'next/font/google' +import { Rubik } from 'next/font/google' + +const inter = Inter({ + subsets: ['latin'], + weight: ['400', '500', '600', '700'], + }) +const rubik = Rubik({ + subsets: ['latin'], + weight: ['400', '500', '600', '700'], +}) +const LinkedFriend = (props : any) => { + const router = useRouter(); + const handleClick = (id : any) => { + router.push(`/Dashboard/Profile?id=${id}`); + } + return ( +
+
+ {/* profile */} + handleClick(props.user?.id)} + alt='profile' + height={50} + width={50} + src={props.user?.picture || '/b.png'} + className="object-cover cursor-pointer !m-0 !p-0 object-top rounded-full h-[50px] w-[50px] border-2 group-hover:scale-105 group-hover:z-30 border-white relative transition duration-500" + /> +
+ {props.user?.name} +

@{props.user?.username}

+
+
+
#{props?.index}
+
+ ) +} + +export default LinkedFriend \ No newline at end of file diff --git a/app/components/Dashboard/Profile/UserProfile.tsx b/app/components/Dashboard/Profile/UserProfile.tsx index 5cacc5e..1214456 100644 --- a/app/components/Dashboard/Profile/UserProfile.tsx +++ b/app/components/Dashboard/Profile/UserProfile.tsx @@ -3,10 +3,16 @@ import React, { use, useEffect, useState } from "react"; import Image from "next/image"; import { useGlobalState } from "../../Sign/GlobalState"; import { Dropdown } from "./Dropdown"; -import Userstatus from "./Userstatus"; import { PinContainer } from "@/components/ui/3d-pin"; - +import {motion} from "framer-motion"; import axios from "axios"; +import Userstatus from "./Userstatus"; +import { Rajdhani } from "next/font/google"; +import { Inter } from "next/font/google"; +import LinkedFriend from "./LinkedFriend"; + +const inter = Inter({ subsets: ["latin"] }); +const rajdhani = Rajdhani({ subsets: ["latin"], weight: ["400", "500"] }); const people = [ { @@ -165,68 +171,139 @@ const UserProfile = ({target} : any) => { return (
-
-
- -
- bg +
+
+ +
+ { + target ? ( + bg + ) : ( +
+ +
+ ) + }
blockUser("blockFriend")} handleUnblock={() => blockUser("unblockFriend")} status={status} recv={recv} />
-
+
- profile + {target ? ( + profile + ) : ( +
+ +
+ )}
-
-

- {target.name} -

- @{target.username} - 400,000 + { + target ? ( +
+

+ {target?.name} +

+ + @{target?.username} + + 400,000 +
+ ) :( +
+
+
+
+
+ ) + } +
+
+
+ +
+
+
+
+
+ badge +
+
+
+

+ LVL 2 +

+ + 250/1000 + +
+
+ +
+
+
+
+ 45% +
+
+
+
+ + +
+

+ Linked Friends +

+
+ { + linkedFriends && linkedFriends?.map((user, i) => { + return ( + + ); + }) + } +
+
-
); diff --git a/app/components/Dashboard/Profile/Userstatus.tsx b/app/components/Dashboard/Profile/Userstatus.tsx index 1392939..963b289 100644 --- a/app/components/Dashboard/Profile/Userstatus.tsx +++ b/app/components/Dashboard/Profile/Userstatus.tsx @@ -1,57 +1,20 @@ import React from 'react' -import { Inter } from "next/font/google"; import { Button } from "@/components/ui/moving-border" import Image from 'next/image' import { AnimatedTooltip } from '@/components/ui/animated-tooltip' import { getDate } from '@/app/utils' +import { Rajdhani } from "next/font/google"; +import { Inter } from "next/font/google"; const inter = Inter({ subsets: ["latin"] }); +const rajdhani = Rajdhani({ subsets: ["latin"], weight: ["400", "500"] }); -const Userstatus = ({target, status, recv, friendReq, removeFriend, handleSender, linkedFriends} : any) => { +const Userstatus = ({target, status, recv, friendReq, removeFriend, handleSender} : any) => { return ( -
-
-
-
-
- badge -
-
-
-

- LVL 2 -

- - 250/1000 - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
+
+
friendReq("acceptFriendRequest")} borderRadius="1.75rem" borderClassName=" bg-[radial-gradient(var(--green-500)_40%,transparent_60%)]" - className={`text-white border-slate-800 w-full sm:mt-0 mt-4 bg-green-500/[0.3]`} + className={`text-white border-slate-800 w-full sm:mt-0 mt-4 bg-green-500/[0.5]`} > ACCEPTE @@ -109,7 +72,7 @@ const Userstatus = ({target, status, recv, friendReq, removeFriend, handleSender onClick={() => friendReq("rejectFriendRequest")} borderRadius="1.75rem" borderClassName=" bg-[radial-gradient(var(--red-500)_40%,transparent_60%)]" - className={`text-white border-slate-800 w-full sm:mt-0 mt-4 bg-red-500/[0.3]`} + className={`text-white border-slate-800 w-full sm:mt-0 mt-4 bg-[#FF4654]/[0.6]`} > REJECTE @@ -119,7 +82,7 @@ const Userstatus = ({target, status, recv, friendReq, removeFriend, handleSender onClick={removeFriend} borderRadius="1.75rem" borderClassName="bg-[radial-gradient(var(--red-500)_40%,transparent_60%)]" - className={`text-white border-slate-800 w-full sm:mt-0 mt-4 bg-red-500/[0.3]`} + className={`text-white border-slate-800 w-full sm:mt-0 mt-4 bg-[#FF4654]/[0.6]`} > REMOVE FRIEND @@ -129,7 +92,7 @@ const Userstatus = ({target, status, recv, friendReq, removeFriend, handleSender onClick={handleSender} borderRadius="1.75rem" borderClassName={status === "ACCEPTED" ? "bg-[radial-gradient(var(--red-500)_40%,transparent_60%)]" : ""} - className={`text-white border-slate-800 w-full sm:mt-0 mt-4 ${status === "PENDING" ? "bg-slate-800" : status === "ACCEPTED" ? "bg-red-600/[0.3]" : ""}`} + className={`text-white border-slate-800 w-full sm:mt-0 mt-4 ${status === "PENDING" ? "bg-slate-600" : status === "ACCEPTED" ? "bg-red-600/[0.3]" : ""}`} > { status && status === "PENDING" ? "PENDING" @@ -138,10 +101,8 @@ const Userstatus = ({target, status, recv, friendReq, removeFriend, handleSender } } -
-
-
-
+
+
) } diff --git a/app/components/Dashboard/Search/UserCard.tsx b/app/components/Dashboard/Search/UserCard.tsx index c755a86..e1e8a1a 100644 --- a/app/components/Dashboard/Search/UserCard.tsx +++ b/app/components/Dashboard/Search/UserCard.tsx @@ -16,7 +16,7 @@ const UserCard = ({user}: Props) => { return (
- + { @{user?.username} @@ -48,15 +48,4 @@ const UserCard = ({user}: Props) => { ) } - export default UserCard - //
- // Profile - //
{user.name}
- //
@{user.username}
- //
\ No newline at end of file + export default UserCard \ No newline at end of file diff --git a/app/components/Dashboard/Settings/EditProfile.tsx b/app/components/Dashboard/Settings/EditProfile.tsx index 33a66fc..b66d5a0 100644 --- a/app/components/Dashboard/Settings/EditProfile.tsx +++ b/app/components/Dashboard/Settings/EditProfile.tsx @@ -3,6 +3,11 @@ import React, { useState } from 'react' import Image from 'next/image' import { useForm } from 'react-hook-form'; import { useGlobalState } from '../../Sign/GlobalState'; + +import { cn } from "@/components/cn"; +import { Label } from "@/components/ui/newlabel"; +import { Input } from "@/components/ui/newinput"; + import axios from 'axios'; const EditProfile = () => { @@ -115,22 +120,16 @@ const EditProfile = () => {
- - + + + +
- - + + + +
@@ -142,4 +141,18 @@ const EditProfile = () => { ) } -export default EditProfile \ No newline at end of file +export default EditProfile + +const LabelInputContainer = ({ + children, + className, +}: { + children: React.ReactNode; + className?: string; +}) => { + return ( +
+ {children} +
+ ); +}; \ No newline at end of file diff --git a/app/components/Dashboard/Settings/Security.tsx b/app/components/Dashboard/Settings/Security.tsx index 930ef89..7efaf7b 100644 --- a/app/components/Dashboard/Settings/Security.tsx +++ b/app/components/Dashboard/Settings/Security.tsx @@ -2,6 +2,11 @@ import React, { useEffect, useState } from 'react' import { useGlobalState } from '../../Sign/GlobalState' import Image from 'next/image' + +import { cn } from "@/components/cn"; +import { Label } from "@/components/ui/newlabel"; +import { Input } from "@/components/ui/newinput"; + import axios from 'axios' import { useForm } from 'react-hook-form' import EnterCode from './otp' @@ -115,22 +120,16 @@ const Security = () => {
- - + + + +
- - + + + +
@@ -194,33 +193,18 @@ const Security = () => { } export default Security - //
- // - // - // {showPopup && ( - // - //
- // { qrcode && qrcode } - // - // - // - // - //
- //
- // )} - //
\ No newline at end of file + + +const LabelInputContainer = ({ + children, + className, +}: { + children: React.ReactNode; + className?: string; +}) => { + return ( +
+ {children} +
+ ); +}; \ No newline at end of file diff --git a/app/components/Dashboard/Settings/otp.tsx b/app/components/Dashboard/Settings/otp.tsx index 8dd46a2..641f3a1 100644 --- a/app/components/Dashboard/Settings/otp.tsx +++ b/app/components/Dashboard/Settings/otp.tsx @@ -95,7 +95,8 @@ export default function EnterCode({ register, isError , reset}: any) {
{[0, 1, 2, 3, 4, 5].map((index) => ( {
{notifed && ( -
+
)} From e53f165ed22b84db53bd1b1c91c2ffc95e10cabd Mon Sep 17 00:00:00 2001 From: Mohamed Jarboua Date: Wed, 13 Mar 2024 16:52:26 +0000 Subject: [PATCH 03/32] added something to the front end --- app/components/Dashboard/Chat/JoinChannel.tsx | 50 ++++++++++++++----- .../Dashboard/Chat/JoinChannelBubble.tsx | 20 +++++++- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/app/components/Dashboard/Chat/JoinChannel.tsx b/app/components/Dashboard/Chat/JoinChannel.tsx index 86c55d7..0ff3de2 100644 --- a/app/components/Dashboard/Chat/JoinChannel.tsx +++ b/app/components/Dashboard/Chat/JoinChannel.tsx @@ -28,31 +28,44 @@ const modalVariants = { }, }; - -const JoinChannel = ({ handleClick, user }: { handleClick: () => void, user: user }) => { +const JoinChannel = ({ + handleClick, + user, + socket, +}: { + handleClick: () => void; + user: user; + socket: any; +}) => { const [channels, setChannels] = useState([]); const [filteredChannels, setFilteredChannels] = useState([]); const search = useRef(null); const { register } = useForm(); useEffect(() => { const fetchChannels = async () => { - const res = await axios.get("http://localhost:8080/channels").then((data) => { - setChannels(data.data); - setFilteredChannels(data.data); - }); + const res = await axios + .get("http://localhost:8080/channels") + .then((data) => { + setChannels(data.data); + setFilteredChannels(data.data); + }); }; - fetchChannels(); + fetchChannels(); }, []); const filterBySearch = (e: React.ChangeEvent, value: string | null) => { - const res = channels.filter((channel) => { - return channel.name.toLowerCase().includes(value?.toLowerCase() as string); - }); + const res = channels.filter((channel) => { + return channel.name + .toLowerCase() + .includes(value?.toLowerCase() as string); + }); setFilteredChannels(res); }; return ( -