Skip to content

Commit d2d4d22

Browse files
committed
feat: styling profile page, message page and fixed modal transition
1 parent 56b4caa commit d2d4d22

21 files changed

+362
-134
lines changed

components/AblyChatComponent.jsx

+37-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ import { useAuthContext } from "../hooks/useAuthContext";
44
import { collection, addDoc, getDocs, query, where } from "firebase/firestore";
55
import { db } from "../firebase/config";
66
import { useRouter } from "next/router";
7+
import styles from "../css/chat.module.css";
8+
import { motion } from "framer-motion";
9+
10+
const buttonVariants = {
11+
hover: {
12+
scale: 1.06,
13+
},
14+
tap: {
15+
scale: 0.99,
16+
},
17+
};
718

819
const AblyChatComponent = (props) => {
920
const { user } = useAuthContext();
@@ -67,11 +78,12 @@ const AblyChatComponent = (props) => {
6778
sendChatMessage(messageText);
6879
event.preventDefault();
6980
};
81+
7082
const previousMessages = messageHistory.map((msg, index) => {
7183
console.log(msg);
7284
return (
7385
<section key={index}>
74-
<span>
86+
<span className={styles.prevMessage}>
7587
{msg.user.stringValue}: {msg.message.stringValue}
7688
</span>
7789
<br />
@@ -84,9 +96,12 @@ const AblyChatComponent = (props) => {
8496

8597
return (
8698
<section key={index}>
87-
<span data-author={author}>
88-
{message.name}: {message.data}
89-
</span>
99+
<div className={styles.messages}>
100+
<span data-author={author} className={styles.newMessage}>
101+
{message.name}: {message.data}
102+
</span>
103+
</div>
104+
90105
<br />
91106
</section>
92107
);
@@ -98,31 +113,42 @@ const AblyChatComponent = (props) => {
98113
></div>;
99114

100115
return (
101-
<main style={{ marginTop: "92px" }}>
116+
<main className={styles.chatContainer}>
102117
<div>
103-
{previousMessages}
104-
{messages}
118+
<div className={styles.message}>
119+
<div>{previousMessages}</div>
120+
<div>{messages}</div>
121+
</div>
122+
105123
<div
106124
ref={(element) => {
107125
messageEnd = element;
108126
}}
109127
></div>
110128
</div>
111-
<form onSubmit={handleFormSubmission}>
129+
<form onSubmit={handleFormSubmission} className={styles.form}>
112130
<textarea
131+
className={styles.textArea}
113132
ref={(element) => {
114133
inputBox = element;
115134
}}
116135
placeholder="Type a message..."
117136
onChange={(e) => setMessageText(e.target.value)}
118137
onKeyPress={handleKeyPress}
119138
></textarea>
120-
<button type="submit" disabled={messageTextIsEmpty}>
139+
<motion.button
140+
variants={buttonVariants}
141+
whileHover="hover"
142+
whileTap="tap"
143+
type="submit"
144+
disabled={messageTextIsEmpty}
145+
className={styles.button}
146+
>
121147
Send
122-
</button>
148+
</motion.button>
123149
</form>
124150
</main>
125151
);
126152
};
127153

128-
export default AblyChatComponent;
154+
export default AblyChatComponent;

components/Footer.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default function Footer() {
2020
<div className={styles.teamMembers}>
2121
<div className={styles.heading}>Team Array of Sunshine</div>
2222
<div className={styles.notLastTeamMember}>
23-
<a href="https://github.com/Nasramohammed">Nasramohammed</a>
23+
<a href="https://github.com/Nasramohammed">Nasra</a>
2424
</div>
2525
<div className={styles.notLastTeamMember}>
2626
<a href="https://github.com/richnw">Rich</a>

components/Layout.jsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import LoggedInNav from "./LoggedInNav";
44
import LoggedOutNav from "./LoggedOutNav";
55
import { useRouter } from "next/router";
66

7-
import styles from "../css/layout.module.css";
7+
88

99
export default function Layout({ children }) {
1010
const { user } = useAuthContext();
@@ -19,7 +19,7 @@ export default function Layout({ children }) {
1919
return (
2020
<div>
2121
{user ? <LoggedInNav /> : <LoggedOutNav />}
22-
<div className={styles.main}>{children}</div>
22+
<div >{children}</div>
2323
<Footer />
2424
</div>
2525
);

components/LoggedInNav.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export default function LoggedInNav() {
5757
<Link href={"/home"}>
5858
<Image className={styles.logoStyle} alt="logo" src={logo} />
5959
</Link>
60-
{showModal && modal}
60+
{modal}
6161
<GiHamburgerMenu
6262
onClick={() => {
6363
setShowModal(!showModal);

components/LoggedOutNav.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default function LoggedOutNav() {
4141
<Link href="/">
4242
<Image className={styles.logoStyle} alt="logo" src={logo} />
4343
</Link>
44-
{showModal && modal}
44+
{ modal}
4545
<GiHamburgerMenu onClick={()=>{
4646
setShowModal(!showModal)
4747
}} className={styles.hamburgerMenuStyle} />

components/Modal.jsx

+18-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
1-
2-
import React from "react";
1+
import React, { useEffect } from "react";
32
import styles from "../css/modal.module.css";
43

54
export default function Modal({ children, setShowModal, showModal }) {
5+
useEffect(() => {
6+
if (showModal) {
7+
document.body.style.overflow = "hidden";
8+
} else {
9+
document.body.style.overflow = "unset";
10+
}
11+
return () => {
12+
document.body.style.overflow = "unset";
13+
};
14+
}, [showModal]);
15+
616
return (
7-
<div className={styles.overlay}>
8-
<div className={styles.modal}>
17+
<div
18+
className={`${styles.overlay} ${showModal ? styles["show-overlay"] : ""}`}
19+
>
20+
<div
21+
className={`${styles.modal} ${showModal ? styles["show-modal"] : ""}`}
22+
>
923
<div className={styles.closeBtn}>
1024
<div
1125
onClick={() => {

components/PastPosts.jsx

+14-15
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import styles from '../css/pastPosts.module.css';
2-
import { collection, query, where, getDocs } from 'firebase/firestore';
3-
import { db } from '../firebase/config';
4-
import { useEffect, useState } from 'react';
5-
import ProfilePagePostCard from './ProfilePagePostCard';
6-
import { useRouter } from 'next/router';
1+
import styles from "../css/pastPosts.module.css";
2+
import { collection, query, where, getDocs } from "firebase/firestore";
3+
import { db } from "../firebase/config";
4+
import { useEffect, useState } from "react";
5+
import ProfilePagePostCard from "./ProfilePagePostCard";
6+
import { useRouter } from "next/router";
77

88
export default function PastPosts() {
99
const [pastPosts, setPastPosts] = useState([]);
@@ -16,10 +16,10 @@ export default function PastPosts() {
1616
setIsLoading(true);
1717
if (!router.isReady || !userNameFromParams) return;
1818
const getUserPosts = async () => {
19-
const postsCol = collection(db, 'posts');
19+
const postsCol = collection(db, "posts");
2020
const postQuery = query(
2121
postsCol,
22-
where('user', '==', userNameFromParams)
22+
where("user", "==", userNameFromParams)
2323
);
2424

2525
const postsSnapshot = await getDocs(postQuery);
@@ -38,12 +38,11 @@ export default function PastPosts() {
3838

3939
if (isLoading) return <div>Loading...</div>;
4040
return (
41-
<div>
42-
<div className={styles.pastPostContainer}>
43-
{pastPosts?.map((post) => {
44-
return <ProfilePagePostCard key={post.postId} props={post} />;
45-
})}
46-
</div>
41+
<div className={styles.pastPostContainer}>
42+
<div className={styles.subHeader}>Past Posts</div>
43+
{pastPosts?.map((post) => {
44+
return <ProfilePagePostCard key={post.postId} props={post} />;
45+
})}
4746
</div>
4847
);
49-
}
48+
}

components/ProfilePagePostCard.jsx

+16-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import React from 'react';
2-
import styles from '../css/profilePagePostCard.module.css';
1+
import React from "react";
2+
import styles from "../css/profilePagePostCard.module.css";
3+
import imagePlaceholder from "../images/image-placeholder.svg";
4+
import Image from "next/image";
35

46
export default function ProfilePagePostCard({ props }) {
57
const {
@@ -13,19 +15,25 @@ export default function ProfilePagePostCard({ props }) {
1315
user,
1416
} = props;
1517
const date = new Date(postTime);
16-
const readableDate = date.toLocaleDateString('en-GB');
17-
const readableTime = date.toLocaleTimeString('en-GB').slice(0, 5);
18+
const readableDate = date.toLocaleDateString("en-GB");
19+
const readableTime = date.toLocaleTimeString("en-GB").slice(0, 5);
1820

1921
return (
2022
<div className={styles.profileCardContainer}>
21-
<div>{postTitle}</div>
22-
<div>{projectDescription}</div>
23+
<div className={styles.title}>{postTitle}</div>
24+
<div className={styles.description}>{projectDescription}</div>
25+
<Image
26+
src={imagePlaceholder}
27+
alt="placeholder"
28+
width={300}
29+
height={300}
30+
/>
2331
<div className={styles.authorAndPostTimeContainer}>
2432
<div>Posted by: {user}</div>
2533
<div>
26-
Created: {readableDate} at {readableTime}{' '}
34+
Created: {readableDate} at {readableTime}{" "}
2735
</div>
2836
</div>
2937
</div>
3038
);
31-
}
39+
}

components/UserProfile.jsx

+22-10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { useAuthContext } from "../hooks/useAuthContext";
1212
export default function UserProfile({ userName }) {
1313
const [profilePageUser, setProfilePageUser] = useState({});
1414
const [isLoading, setIsLoading] = useState(true);
15+
const [showModal, setShowModal] = useState(false);
1516
const { user } = useAuthContext();
1617
const router = useRouter();
1718
const userNameFromParams = router.query.displayname;
@@ -21,9 +22,8 @@ export default function UserProfile({ userName }) {
2122
function createChannel() {
2223
if (user.displayName > userNameFromParams) {
2324
messageChannel = userNameFromParams + user.displayName;
24-
} else
25-
messageChannel = user.displayName + userNameFromParams;
26-
return messageChannel;
25+
} else messageChannel = user.displayName + userNameFromParams;
26+
return messageChannel;
2727
}
2828

2929
// if (user.displayName !== null && user.displayName > userNameFromParams) {
@@ -76,14 +76,26 @@ export default function UserProfile({ userName }) {
7676
<h2 className={styles.displayName}>{userNameFromParams}</h2>
7777
{isSomeoneElsesProfile ? (
7878
<div className={styles.contactOtherUser}>
79-
<button onClick={() => router.push({ pathname: `/message/${createChannel()}`,
80-
query: {secondUser: `${userNameFromParams}`}
81-
})}>
82-
83-
<TbMessage2 size={30} style={{ color: "white" }} />
79+
<button
80+
className={styles.messageButton}
81+
onClick={() =>
82+
router.push({
83+
pathname: `/message/${createChannel()}`,
84+
query: { secondUser: `${userNameFromParams}` },
85+
})
86+
}
87+
>
88+
<TbMessage2 size={30} />
8489
</button>
8590

86-
<AiOutlinePhone size={30} style={{ color: "white" }} />
91+
<button
92+
className={styles.messageButton}
93+
onClick={() => {
94+
router.push("/video");
95+
}}
96+
>
97+
<AiOutlinePhone size={30} />
98+
</button>
8799
</div>
88100
) : null}
89101
</div>
@@ -97,4 +109,4 @@ export default function UserProfile({ userName }) {
97109
</div>
98110
</main>
99111
);
100-
}
112+
}

css/chat.module.css

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
.container {
2+
display: flex;
3+
height: 100vh;
4+
5+
}
6+
7+
.chatContainer {
8+
display: flex;
9+
flex-direction: column;
10+
justify-content: flex-end;
11+
align-items: flex-start;
12+
padding: 0px 20px 20px 20px;
13+
gap: 50px;
14+
}
15+
16+
.textArea {
17+
height: 100%;
18+
width: 400px;
19+
resize: none;
20+
font-size: 1.2em;
21+
padding: 10px 20px;
22+
}
23+
24+
.button {
25+
background: #4f9cf9;
26+
color: #ffffff;
27+
border: none;
28+
cursor: pointer;
29+
font-size: 1.2em;
30+
padding: 20px 40px;
31+
border-radius: 5px;
32+
align-self: flex-end;
33+
}
34+
35+
.form {
36+
display: flex;
37+
align-items: flex-end;
38+
gap: 20px;
39+
}
40+
41+
.messages {
42+
display: flex;
43+
flex-direction: column;
44+
gap: 20px;
45+
width: 400px;
46+
height: 100%;
47+
}
48+
49+
.message {
50+
display: flex;
51+
flex-direction: column;
52+
gap: 10px;
53+
border-radius: 5px;
54+
}

0 commit comments

Comments
 (0)