Skip to content

Commit

Permalink
Merge pull request #45 from johnlcos/newlayout
Browse files Browse the repository at this point in the history
Newlayout
  • Loading branch information
johnlcos authored May 1, 2024
2 parents 4673fc5 + 87b9e46 commit 8ef422b
Show file tree
Hide file tree
Showing 37 changed files with 319 additions and 2,965 deletions.
144 changes: 72 additions & 72 deletions client/app/(protected)/(main)/(profile)/[username]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
'use client';
import { useContext, useEffect, useState } from 'react';
import { FollowButton } from '@/components/follow-button';
import { SessionContext } from '@/app/(protected)/layout';
import { FaUserCircle } from 'react-icons/fa';
import { MainFeed } from '@/components/main-feed';
import { useRouter } from 'next/navigation';
import Image from 'next/image';
import { Avatar } from '@/components/avatar';
import { ProfileFeed } from '@/components/profile-feed';
import { socket } from '@/socket';
"use client";
import { useContext, useEffect, useState } from "react";
import { FollowButton } from "@/components/follow-button";
import { SessionContext } from "@/app/(protected)/layout";
import { FaUserCircle } from "react-icons/fa";
import { MainFeed } from "@/components/main-feed";
import { useRouter } from "next/navigation";
import Image from "next/image";
import { Avatar } from "@/components/avatar";
import { ProfileFeed } from "@/components/profile-feed";
import { socket } from "@/socket";

export default function UserProfile({
params,
Expand All @@ -20,10 +20,10 @@ export default function UserProfile({
const { userSession, setUserSession } = useContext(SessionContext);
// store the profile information in state
// const [username, setUsername] = useState<string>(params.username);
const [displayName, setDisplayName] = useState<string>('');
const [description, setDescription] = useState<string>('');
const [avatarUrl, setAvatarUrl] = useState<string | null>('');
const [profileId, setProfileId] = useState<string>('');
const [displayName, setDisplayName] = useState<string>("");
const [description, setDescription] = useState<string>("");
const [avatarUrl, setAvatarUrl] = useState<string | null>("");
const [profileId, setProfileId] = useState<string>("");
// store status in state for conditional rendering
const [uploading, setUploading] = useState<boolean>(false);
const [editing, setEditing] = useState<boolean>(false);
Expand All @@ -34,15 +34,15 @@ export default function UserProfile({
description: string;
avatarUrl: string | null;
}>({
displayName: '',
description: '',
avatarUrl: '',
displayName: "",
description: "",
avatarUrl: "",
});
// store the path and file in state when uploading a new avatar
const [newAvatar, setNewAvatar] = useState<{
path: string;
file: File | null;
}>({ path: '', file: null });
}>({ path: "", file: null });
// store the number of followers and following in state
const [followers, setFollowers] = useState<number>(0);
const [following, setFollowing] = useState<number>(0);
Expand All @@ -54,7 +54,7 @@ export default function UserProfile({
//! Might not need this
// after updating info, get the new session which includes updated username in meta data and update the session context for use in sidebar
const getCurrentSession = async () => {
const response = await fetch('http://localhost:8080/auth/session');
const response = await fetch("http://localhost:8080/auth/session");
const json = await response.json();
const session = await json.data.session;
console.log(session);
Expand All @@ -67,10 +67,10 @@ export default function UserProfile({
`http://localhost:8080/users/info?user=${params.username}`
);
const json = await response.json();
console.log('fetchProfileInfo: ', json);
console.log("fetchProfileInfo: ", json);
setDisplayName(json.data[0].display_name);
setProfileId(json.data[0].id);
setDescription(json.data[0].description || '');
setDescription(json.data[0].description || "");
setAvatarUrl(json.data[0].profile_avatar);
setFollowers(json.followers);
setFollowing(json.following);
Expand All @@ -89,17 +89,17 @@ export default function UserProfile({
const handleSaveEdits = async (e: React.ChangeEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.target);
formData.append('id', profileId);
formData.append("id", profileId);
if (newAvatar.file) {
formData.append('file', newAvatar.file);
formData.append('path', newAvatar.path);
formData.append("file", newAvatar.file);
formData.append("path", newAvatar.path);
}
const response = await fetch('http://localhost:8080/users/edit', {
method: 'POST',
const response = await fetch("http://localhost:8080/users/edit", {
method: "POST",
body: formData,
});
const url = await response.json();
console.log('url', url);
console.log("url", url);
if (url && url.publicUrl) {
setAvatarUrl(url.publicUrl);
}
Expand All @@ -122,13 +122,13 @@ export default function UserProfile({
// setUploading(true);

if (!event.target.files || event.target.files.length === 0) {
throw new Error('You must select an image to upload.');
throw new Error("You must select an image to upload.");
}

const file = event.target.files[0];
const previewUrl = URL.createObjectURL(file);
setAvatarUrl(previewUrl);
const fileExt = file.name.split('.').pop();
const fileExt = file.name.split(".").pop();
const fileName = `avatar_${profileId}.${fileExt}?date=${Date.now()}`;
const filePath = `${fileName}`;
setNewAvatar({ path: filePath, file: file });
Expand All @@ -138,86 +138,86 @@ export default function UserProfile({
const response = await fetch(
`http://localhost:8080/messages/room?userId=${profileId}`,
{
method: 'POST',
method: "POST",
}
);
const result = await response.json();
const chatId = result.chatId;
const user1 = userSession?.user.user_metadata.display_name;
const user2 = displayName;
console.log(chatId);
const user = userSession?.user.user_metadata.display_name;
console.log("Start Chatroom: ", chatId);
if (chatId) {
socket.emit('join_room', { chatId, user1, user2 });
console.log("Emmitting join_room");
socket.emit("join_room", { chatId, user });
}

router.push(`/${params.username}/${chatId}`);
};

return loading ? null : (
<div className='w-full flex flex-col items-center'>
<div className="w-full flex flex-col items-center">
<form
id='header'
className='w-full flex flex-col items-center xl:flex-row
xl:content-between px-5 py-8 gap-8 h-[575px] md:h-[525px] lg:h-[540px] xl:h-[325px]'
encType='multipart/form-data'
id="header"
className="w-full flex flex-col items-center xl:flex-row
xl:content-between px-5 py-8 gap-8 h-[575px] md:h-[525px] lg:h-[540px] xl:h-[325px]"
encType="multipart/form-data"
onSubmit={handleSaveEdits}
>
<div className='flex flex-col items-center w-min gap-6'>
<div className="flex flex-col items-center w-min gap-6">
<label
htmlFor='avatarUpload'
className='relative inline-block w-48 h-48'
htmlFor="avatarUpload"
className="relative inline-block w-48 h-48"
>
<Avatar url={avatarUrl} type='profile' />
<Avatar url={avatarUrl} type="profile" />
<input
type='file'
id='avatarUpload'
accept='image/*'
className='opacity-0 absolute inset-0 w-full h-full enabled:cursor-pointer disabled:invisible'
type="file"
id="avatarUpload"
accept="image/*"
className="opacity-0 absolute inset-0 w-full h-full enabled:cursor-pointer disabled:invisible"
onChange={handleAvatarChange}
disabled={uploading || !editing}
/>
</label>

{!editing ? (
<h1 className='text-[#E4E6EB]'>{displayName}</h1>
<h1 className="text-[#E4E6EB]">{displayName}</h1>
) : (
<input
className='resize-none rounded-lg text-[#E4E6EB] bg-gray-700 dark-border-gray-600focus:ring-blue-500 focus:border-blue-500 text-center'
name='displayName'
id='edit-profile-displayName'
className="resize-none rounded-lg text-[#E4E6EB] bg-gray-700 dark-border-gray-600focus:ring-blue-500 focus:border-blue-500 text-center"
name="displayName"
id="edit-profile-displayName"
value={displayName}
onChange={(e) => setDisplayName(e.target.value)}
></input>
)}
</div>
<div className='flex w-full h-full xl:w-[500px] items-center'>
<div className="flex w-full h-full xl:w-[500px] items-center">
{!editing ? (
<p className='w-full h-full text-[#E4E6EB] p-2 break-all'>
<p className="w-full h-full text-[#E4E6EB] p-2 break-all">
{description}
</p>
) : (
<textarea
className='p-2 w-full h-full resize-none rounded-lg text-[#E4E6EB] bg-gray-700 dark-border-gray-600 focus:ring-blue-500 focus:border-blue-500 break-all'
name='description'
id='edit-profile-description'
className="p-2 w-full h-full resize-none rounded-lg text-[#E4E6EB] bg-gray-700 dark-border-gray-600 focus:ring-blue-500 focus:border-blue-500 break-all"
name="description"
id="edit-profile-description"
maxLength={300}
value={description}
onChange={(e) => setDescription(e.target.value)}
></textarea>
)}
</div>
<div className='flex w-10/12 items-center justify-start gap-2 flex-col xl:items-start xl:h-full xl:w-min'>
<div className='flex gap-2 xl:flex-col'>
<p className='text-white flex gap-1'>
<div className="flex w-10/12 items-center justify-start gap-2 flex-col xl:items-start xl:h-full xl:w-min">
<div className="flex gap-2 xl:flex-col">
<p className="text-white flex gap-1">
{following}
<span className='text-[#71767A]'>Following</span>
<span className="text-[#71767A]">Following</span>
</p>
<p className='text-white flex gap-1'>
<p className="text-white flex gap-1">
{followers}
<span className='text-[#71767A]'>Followers</span>
<span className="text-[#71767A]">Followers</span>
</p>
</div>
<div className='flex xl:flex-col gap-2'>
<div className="flex xl:flex-col gap-2">
{userSession && userSession.user.id !== profileId ? (
<FollowButton
followed_id={profileId}
Expand All @@ -226,17 +226,17 @@ export default function UserProfile({
) : !editing ? (
<button
onClick={handleStartEdits}
className='text-white bg-green-700 hover:bg-green-800 font-medium rounded-lg text-sm transition duration-300 w-[100px] h-[32px] flex justify-center items-center'
className="text-white bg-green-700 hover:bg-green-800 font-medium rounded-lg text-sm transition duration-300 w-[100px] h-[32px] flex justify-center items-center"
>
Edit Profile
</button>
) : (
<button
type='submit'
className='text-white bg-green-700 hover:bg-green-800
type="submit"
className="text-white bg-green-700 hover:bg-green-800
font-medium rounded-lg text-sm transition
duration-300 w-[100px] h-[32px] flex
justify-center items-center'
justify-center items-center"
disabled={
prevProfile.displayName === displayName &&
prevProfile.description === description &&
Expand All @@ -249,20 +249,20 @@ export default function UserProfile({
{editing ? (
<button
onClick={handleCancelEdits}
className='text-white bg-red-700 hover:bg-red-800
className="text-white bg-red-700 hover:bg-red-800
font-medium rounded-lg text-sm transition
duration-300 w-[100px] h-[32px]
flex justify-center items-center'
flex justify-center items-center"
>
Cancel
</button>
) : null}
{userSession && userSession.user.id !== profileId && (
<button
className='text-white bg-green-700 hover:bg-green-800
className="text-white bg-green-700 hover:bg-green-800
font-medium rounded-lg text-sm transition
duration-300 w-[100px] h-[32px]
flex justify-center items-center'
flex justify-center items-center"
onClick={handleStartMessage}
>
Message
Expand Down
18 changes: 14 additions & 4 deletions client/app/(protected)/(main)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,20 @@ export default function Layout({
children: React.ReactNode;
}>) {
return (
<div className="w-full h-full flex">
<div className="w-full pl-[16%] lg:pr-[32%]">{children}</div>
<div className="w-2/6 p-0 fixed right-0 bg-background hidden h-screen lg:block z-1">
<RightSideWrapper />
<div id="middle-right-inner" className="w-full h-full flex">
<div
id="middle-wrapper"
className="flex-grow lg:w-[500px] xl:w-[650px] h-full"
>
{children}
</div>
<div
id="right-wrapper"
className="w-[300px] xl:w-[400px] hidden lg:block"
>
<div className="w-[300px] xl:w-[400px] fixed">
<RightSideWrapper />
</div>
</div>
</div>
);
Expand Down
21 changes: 17 additions & 4 deletions client/app/(protected)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,24 @@ export default function Layout({
<ReplyFeedModal />
</div>
{!isLoading && (
<div className="flex w-full h-full">
<div className="w-1/6 fixed h-full">
<SideNavBar />
<div
id="main-wrapper"
className="flex w-full h-full justify-center"
>
<div
id="left-wrapper"
className="w-[80px] md:w-[120px] lg:w-[220px] h-full"
>
<div className="fixed w-[80px] md:w-[120px] lg:w-[220px] h-full">
<SideNavBar />
</div>
</div>
<div
id="middle-right-wrapper"
className="flex-grow lg:flex-grow-0 lg:w-[800px] xl:w-[1050px] h-full"
>
{children}
</div>
<div className="flex-grow h-full">{children}</div>
</div>
)}
</div>
Expand Down
6 changes: 6 additions & 0 deletions client/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,10 @@
text-text-white font-semibold shadow-md hover:bg-primary-600
transition duration-300 flex items-center justify-center gap-2;
}

.input {
@apply bg-background border border-gray-300 text-text-white
text-sm rounded-lg w-full p-2.5 focus:ring-primary-500
focus:border-primary-500 focus:ring-2 focus:outline-none;
}
}
Loading

0 comments on commit 8ef422b

Please sign in to comment.