Skip to content

Commit

Permalink
3rd part completed - connecting frontend and backend
Browse files Browse the repository at this point in the history
  • Loading branch information
burakorkmez committed Jan 30, 2024
1 parent 7aadf4f commit cecf505
Show file tree
Hide file tree
Showing 28 changed files with 734 additions and 102 deletions.
36 changes: 17 additions & 19 deletions frontend/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
settings: { react: { version: '18.2' } },
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
root: true,
env: { browser: true, es2020: true },
extends: [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"plugin:react-hooks/recommended",
],
ignorePatterns: ["dist", ".eslintrc.cjs"],
parserOptions: { ecmaVersion: "latest", sourceType: "module" },
settings: { react: { version: "18.2" } },
plugins: ["react-refresh"],
rules: {
"react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
"react/prop-types": "off",
},
};
110 changes: 104 additions & 6 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^5.0.1"
"react-hot-toast": "^2.4.1",
"react-icons": "^5.0.1",
"react-router-dom": "^6.21.3",
"zustand": "^4.5.0"
},
"devDependencies": {
"@types/react": "^18.2.43",
Expand Down
13 changes: 12 additions & 1 deletion frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { Navigate, Route, Routes } from "react-router-dom";
import "./App.css";
import Home from "./pages/home/Home";
import Login from "./pages/login/Login";
import SignUp from "./pages/signup/SignUp";
import { Toaster } from "react-hot-toast";
import { useAuthContext } from "./context/AuthContext";

function App() {
const { authUser } = useAuthContext();
return (
<div className='p-4 h-screen flex items-center justify-center'>
<Home />
<Routes>
<Route path='/' element={authUser ? <Home /> : <Navigate to={"/login"} />} />
<Route path='/login' element={authUser ? <Navigate to='/' /> : <Login />} />
<Route path='/signup' element={authUser ? <Navigate to='/' /> : <SignUp />} />
</Routes>
<Toaster />
</div>
);
}
Expand Down
27 changes: 17 additions & 10 deletions frontend/src/components/messages/Message.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
const Message = () => {
import { useAuthContext } from "../../context/AuthContext";
import { extractTime } from "../../utils/extractTime";
import useConversation from "../../zustand/useConversation";

const Message = ({ message }) => {
const { authUser } = useAuthContext();
const { selectedConversation } = useConversation();
const fromMe = message.senderId === authUser._id;
const formattedTime = extractTime(message.createdAt);
const chatClassName = fromMe ? "chat-end" : "chat-start";
const profilePic = fromMe ? authUser.profilePic : selectedConversation?.profilePic;
const bubbleBgColor = fromMe ? "bg-blue-500" : "";

return (
<div className='chat chat-end'>
<div className={`chat ${chatClassName}`}>
<div className='chat-image avatar'>
<div className='w-10 rounded-full'>
<img
alt='Tailwind CSS chat bubble component'
src={
"https://cdn0.iconfinder.com/data/icons/communication-line-10/24/account_profile_user_contact_person_avatar_placeholder-512.png"
}
/>
<img alt='Tailwind CSS chat bubble component' src={profilePic} />
</div>
</div>
<div className={`chat-bubble text-white bg-blue-500`}>Hi! What is upp?</div>
<div className='chat-footer opacity-50 text-xs flex gap-1 items-center'>12:42</div>
<div className={`chat-bubble text-white ${bubbleBgColor} pb-2`}>{message.message}</div>
<div className='chat-footer opacity-50 text-xs flex gap-1 items-center'>{formattedTime}</div>
</div>
);
};
Expand Down
14 changes: 11 additions & 3 deletions frontend/src/components/messages/MessageContainer.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { useEffect } from "react";
import useConversation from "../../zustand/useConversation";
import MessageInput from "./MessageInput";
import Messages from "./Messages";
import { TiMessages } from "react-icons/ti";

const MessageContainer = () => {
const noChatSelected = true;
const { selectedConversation, setSelectedConversation } = useConversation();

useEffect(() => {
// cleanup function (unmounts)
return () => setSelectedConversation(null);
}, [setSelectedConversation]);

return (
<div className='md:min-w-[450px] flex flex-col'>
{noChatSelected ? (
{!selectedConversation ? (
<NoChatSelected />
) : (
<>
{/* Header */}
<div className='bg-slate-500 px-4 py-2 mb-2'>
<span className='label-text'>To:</span>{" "}
<span className='text-gray-900 font-bold'>John doe</span>
<span className='text-gray-900 font-bold'>{selectedConversation.fullName}</span>
</div>
<Messages />
<MessageInput />
Expand Down
18 changes: 16 additions & 2 deletions frontend/src/components/messages/MessageInput.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import { useState } from "react";
import { BsSend } from "react-icons/bs";
import useSendMessage from "../../hooks/useSendMessage";

const MessageInput = () => {
const [message, setMessage] = useState("");
const { loading, sendMessage } = useSendMessage();

const handleSubmit = async (e) => {
e.preventDefault();
if (!message) return;
await sendMessage(message);
setMessage("");
};

return (
<form className='px-4 my-3'>
<form className='px-4 my-3' onSubmit={handleSubmit}>
<div className='w-full relative'>
<input
type='text'
className='border text-sm rounded-lg block w-full p-2.5 bg-gray-700 border-gray-600 text-white'
placeholder='Send a message'
value={message}
onChange={(e) => setMessage(e.target.value)}
/>
<button type='submit' className='absolute inset-y-0 end-0 flex items-center pe-3'>
<BsSend />
{loading ? <div className='loading loading-spinner'></div> : <BsSend />}
</button>
</div>
</form>
Expand Down
Loading

0 comments on commit cecf505

Please sign in to comment.