Skip to content

Commit

Permalink
2nd part completed - ui design
Browse files Browse the repository at this point in the history
burakorkmez committed Jan 29, 2024
1 parent 9180cd3 commit 7aadf4f
Showing 21 changed files with 1,740 additions and 136 deletions.
1,121 changes: 1,117 additions & 4 deletions frontend/package-lock.json

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -11,16 +11,21 @@
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-icons": "^5.0.1"
},
"devDependencies": {
"@types/react": "^18.2.43",
"@types/react-dom": "^18.2.17",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.17",
"daisyui": "^4.6.1",
"eslint": "^8.55.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"postcss": "^8.4.33",
"tailwindcss": "^3.4.1",
"vite": "^5.0.8"
}
}
6 changes: 6 additions & 0 deletions frontend/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Binary file added frontend/public/bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 0 additions & 42 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
@@ -1,42 +0,0 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}

.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}

@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}

.card {
padding: 2em;
}

.read-the-docs {
color: #888;
}
39 changes: 8 additions & 31 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import "./App.css";
import Home from "./pages/home/Home";

function App() {
const [count, setCount] = useState(0)

return (
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.jsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
return (
<div className='p-4 h-screen flex items-center justify-center'>
<Home />
</div>
);
}

export default App
export default App;
19 changes: 19 additions & 0 deletions frontend/src/components/messages/Message.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const Message = () => {
return (
<div className='chat chat-end'>
<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"
}
/>
</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>
);
};
export default Message;
58 changes: 58 additions & 0 deletions frontend/src/components/messages/MessageContainer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import MessageInput from "./MessageInput";
import Messages from "./Messages";
import { TiMessages } from "react-icons/ti";

const MessageContainer = () => {
const noChatSelected = true;
return (
<div className='md:min-w-[450px] flex flex-col'>
{noChatSelected ? (
<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>
</div>
<Messages />
<MessageInput />
</>
)}
</div>
);
};
export default MessageContainer;

const NoChatSelected = () => {
return (
<div className='flex items-center justify-center w-full h-full'>
<div className='px-4 text-center sm:text-lg md:text-xl text-gray-200 font-semibold flex flex-col items-center gap-2'>
<p>Welcome 👋 John Doe ❄</p>
<p>Select a chat to start messaging</p>
<TiMessages className='text-3xl md:text-6xl text-center' />
</div>
</div>
);
};

// STARTER CODE SNIPPET
// import MessageInput from "./MessageInput";
// import Messages from "./Messages";

// const MessageContainer = () => {
// return (
// <div className='md:min-w-[450px] flex flex-col'>
// <>
// {/* 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>
// </div>

// <Messages />
// <MessageInput />
// </>
// </div>
// );
// };
// export default MessageContainer;
40 changes: 40 additions & 0 deletions frontend/src/components/messages/MessageInput.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { BsSend } from "react-icons/bs";

const MessageInput = () => {
return (
<form className='px-4 my-3'>
<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'
/>
<button type='submit' className='absolute inset-y-0 end-0 flex items-center pe-3'>
<BsSend />
</button>
</div>
</form>
);
};
export default MessageInput;

// STARTER CODE SNIPPET
// import { BsSend } from "react-icons/bs";

// const MessageInput = () => {
// return (
// <form className='px-4 my-3'>
// <div className='w-full'>
// <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'
// />
// <button type='submit' className='absolute inset-y-0 end-0 flex items-center pe-3'>
// <BsSend />
// </button>
// </div>
// </form>
// );
// };
// export default MessageInput;
44 changes: 44 additions & 0 deletions frontend/src/components/messages/Messages.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Message from "./Message";

const Messages = () => {
return (
<div className='px-4 flex-1 overflow-auto'>
<Message />
<Message />
<Message />
<Message />
<Message />
<Message />
<Message />
<Message />
<Message />
<Message />
<Message />
<Message />
</div>
);
};
export default Messages;

// STARTER CODE SNIPPET
// import Message from "./Message";

// const Messages = () => {
// return (
// <div className='px-4 flex-1 overflow-auto'>
// <Message />
// <Message />
// <Message />
// <Message />
// <Message />
// <Message />
// <Message />
// <Message />
// <Message />
// <Message />
// <Message />
// <Message />
// </div>
// );
// };
// export default Messages;
54 changes: 54 additions & 0 deletions frontend/src/components/sidebar/Conversation.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const Conversation = () => {
return (
<>
<div className='flex gap-2 items-center hover:bg-sky-500 rounded p-2 py-1 cursor-pointer'>
<div className='avatar online'>
<div className='w-12 rounded-full'>
<img
src='https://cdn0.iconfinder.com/data/icons/communication-line-10/24/account_profile_user_contact_person_avatar_placeholder-512.png'
alt='user avatar'
/>
</div>
</div>

<div className='flex flex-col flex-1'>
<div className='flex gap-3 justify-between'>
<p className='font-bold text-gray-200'>John Doe</p>
<span className='text-xl'>🎃</span>
</div>
</div>
</div>

<div className='divider my-0 py-0 h-1' />
</>
);
};
export default Conversation;

// STARTER CODE SNIPPET
// const Conversation = () => {
// return (
// <>
// <div className='flex gap-2 items-center hover:bg-sky-500 rounded p-2 py-1 cursor-pointer'>
// <div className='avatar online'>
// <div className='w-12 rounded-full'>
// <img
// src='https://cdn0.iconfinder.com/data/icons/communication-line-10/24/account_profile_user_contact_person_avatar_placeholder-512.png'
// alt='user avatar'
// />
// </div>
// </div>

// <div className='flex flex-col flex-1'>
// <div className='flex gap-3 justify-between'>
// <p className='font-bold text-gray-200'>John Doe</p>
// <span className='text-xl'>🎃</span>
// </div>
// </div>
// </div>

// <div className='divider my-0 py-0 h-1' />
// </>
// );
// };
// export default Conversation;
32 changes: 32 additions & 0 deletions frontend/src/components/sidebar/Conversations.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Conversation from "./Conversation";

const Conversations = () => {
return (
<div className='py-2 flex flex-col overflow-auto'>
<Conversation />
<Conversation />
<Conversation />
<Conversation />
<Conversation />
<Conversation />
</div>
);
};
export default Conversations;

// STARTER CODE SNIPPET
// import Conversation from "./Conversation";

// const Conversations = () => {
// return (
// <div className='py-2 flex flex-col overflow-auto'>
// <Conversation />
// <Conversation />
// <Conversation />
// <Conversation />
// <Conversation />
// <Conversation />
// </div>
// );
// };
// export default Conversations;
9 changes: 9 additions & 0 deletions frontend/src/components/sidebar/LogoutButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { BiLogOut } from "react-icons/bi";
const LogoutButton = () => {
return (
<div className='mt-auto'>
<BiLogOut className='w-6 h-6 text-white cursor-pointer' />
</div>
);
};
export default LogoutButton;
28 changes: 28 additions & 0 deletions frontend/src/components/sidebar/SearchInput.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { IoSearchSharp } from "react-icons/io5";

const SearchInput = () => {
return (
<form className='flex items-center gap-2'>
<input type='text' placeholder='Search…' className='input input-bordered rounded-full' />
<button type='submit' className='btn btn-circle bg-sky-500 text-white'>
<IoSearchSharp className='w-6 h-6 outline-none' />
</button>
</form>
);
};
export default SearchInput;

// STARTER CODE SNIPPET
// import { IoSearchSharp } from "react-icons/io5";

// const SearchInput = () => {
// return (
// <form className='flex items-center gap-2'>
// <input type='text' placeholder='Search…' className='input input-bordered rounded-full' />
// <button type='submit' className='btn btn-circle bg-sky-500 text-white'>
// <IoSearchSharp className='w-6 h-6 outline-none' />
// </button>
// </form>
// );
// };
// export default SearchInput;
32 changes: 32 additions & 0 deletions frontend/src/components/sidebar/Sidebar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Conversations from "./Conversations";
import LogoutButton from "./LogoutButton";
import SearchInput from "./SearchInput";

const Sidebar = () => {
return (
<div className='border-r border-slate-500 p-4 flex flex-col'>
<SearchInput />
<div className='divider px-3'></div>
<Conversations />
<LogoutButton />
</div>
);
};
export default Sidebar;

// STARTER CODE FOR THIS FILE
// import Conversations from "./Conversations";
// import LogoutButton from "./LogoutButton";
// import SearchInput from "./SearchInput";

// const Sidebar = () => {
// return (
// <div className='border-r border-slate-500 p-4 flex flex-col'>
// <SearchInput />
// <div className='divider px-3'></div>
// <Conversations />
// <LogoutButton />
// </div>
// );
// };
// export default Sidebar;
76 changes: 18 additions & 58 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
@@ -1,68 +1,28 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;

color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;

font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
@tailwind base;
@tailwind components;
@tailwind utilities;

body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
background: linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)), url("/bg.png");
background-repeat: no-repeat;
background-size: cover;
background-position: center;
}

h1 {
font-size: 3.2em;
line-height: 1.1;
/* dark mode looking scrollbar */
::-webkit-scrollbar {
width: 8px;
}

button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
::-webkit-scrollbar-track {
background: #555;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;

::-webkit-scrollbar-thumb {
background: #121212;
border-radius: 5px;
}

@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
::-webkit-scrollbar-thumb:hover {
background: #242424;
}
12 changes: 12 additions & 0 deletions frontend/src/pages/home/Home.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import MessageContainer from "../../components/messages/MessageContainer";
import Sidebar from "../../components/sidebar/Sidebar";

const Home = () => {
return (
<div className='flex sm:h-[450px] md:h-[550px] rounded-lg overflow-hidden bg-gray-400 bg-clip-padding backdrop-filter backdrop-blur-lg bg-opacity-0'>
<Sidebar />
<MessageContainer />
</div>
);
};
export default Home;
82 changes: 82 additions & 0 deletions frontend/src/pages/login/Login.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const Login = () => {
return (
<div className='flex flex-col items-center justify-center min-w-96 mx-auto'>
<div className='w-full p-6 rounded-lg shadow-md bg-gray-400 bg-clip-padding backdrop-filter backdrop-blur-lg bg-opacity-0'>
<h1 className='text-3xl font-semibold text-center text-gray-300'>
Login
<span className='text-blue-500'> ChatApp</span>
</h1>

<form>
<div>
<label className='label p-2'>
<span className='text-base label-text'>Username</span>
</label>
<input type='text' placeholder='Enter username' className='w-full input input-bordered h-10' />
</div>

<div>
<label className='label'>
<span className='text-base label-text'>Password</span>
</label>
<input
type='password'
placeholder='Enter Password'
className='w-full input input-bordered h-10'
/>
</div>
<a href='#' className='text-sm hover:underline hover:text-blue-600 mt-2 inline-block'>
{"Don't"} have an account?
</a>

<div>
<button className='btn btn-block btn-sm mt-2'>Login</button>
</div>
</form>
</div>
</div>
);
};
export default Login;

// STARTER CODE FOR THIS FILE
// const Login = () => {
// return (
// <div className='flex flex-col items-center justify-center min-w-96 mx-auto'>
// <div className='w-full p-6 rounded-lg shadow-md bg-gray-400 bg-clip-padding backdrop-filter backdrop-blur-lg bg-opacity-0'>
// <h1 className='text-3xl font-semibold text-center text-gray-300'>
// Login
// <span className='text-blue-500'> ChatApp</span>
// </h1>

// <form>
// <div>
// <label className='label p-2'>
// <span className='text-base label-text'>Username</span>
// </label>
// <input type='text' placeholder='Enter username' className='w-full input input-bordered h-10' />
// </div>

// <div>
// <label className='label'>
// <span className='text-base label-text'>Password</span>
// </label>
// <input
// type='password'
// placeholder='Enter Password'
// className='w-full input input-bordered h-10'
// />
// </div>
// <a href='#' className='text-sm hover:underline hover:text-blue-600 mt-2 inline-block'>
// {"Don't"} have an account?
// </a>

// <div>
// <button className='btn btn-block btn-sm mt-2'>Login</button>
// </div>
// </form>
// </div>
// </div>
// );
// };
// export default Login;
40 changes: 40 additions & 0 deletions frontend/src/pages/signup/GenderCheckbox.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const GenderCheckbox = () => {
return (
<div className='flex'>
<div className='form-control'>
<label className={`label gap-2 cursor-pointer`}>
<span className='label-text'>Male</span>
<input type='checkbox' className='checkbox border-slate-900' />
</label>
</div>
<div className='form-control'>
<label className={`label gap-2 cursor-pointer`}>
<span className='label-text'>Female</span>
<input type='checkbox' className='checkbox border-slate-900' />
</label>
</div>
</div>
);
};
export default GenderCheckbox;

// STARTER CODE FOR THIS FILE
// const GenderCheckbox = () => {
// return (
// <div className='flex'>
// <div className='form-control'>
// <label className={`label gap-2 cursor-pointer`}>
// <span className='label-text'>Male</span>
// <input type='checkbox' className='checkbox border-slate-900' />
// </label>
// </div>
// <div className='form-control'>
// <label className={`label gap-2 cursor-pointer`}>
// <span className='label-text'>Female</span>
// <input type='checkbox' className='checkbox border-slate-900' />
// </label>
// </div>
// </div>
// );
// };
// export default GenderCheckbox;
126 changes: 126 additions & 0 deletions frontend/src/pages/signup/SignUp.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import GenderCheckbox from "./GenderCheckbox";

const SignUp = () => {
return (
<div className='flex flex-col items-center justify-center min-w-96 mx-auto'>
<div className='w-full p-6 rounded-lg shadow-md bg-gray-400 bg-clip-padding backdrop-filter backdrop-blur-lg bg-opacity-0'>
<h1 className='text-3xl font-semibold text-center text-gray-300'>
Sign Up <span className='text-blue-500'> ChatApp</span>
</h1>

<form>
<div>
<label className='label p-2'>
<span className='text-base label-text'>Full Name</span>
</label>
<input type='text' placeholder='John Doe' className='w-full input input-bordered h-10' />
</div>

<div>
<label className='label p-2 '>
<span className='text-base label-text'>Username</span>
</label>
<input type='text' placeholder='johndoe' className='w-full input input-bordered h-10' />
</div>

<div>
<label className='label'>
<span className='text-base label-text'>Password</span>
</label>
<input
type='password'
placeholder='Enter Password'
className='w-full input input-bordered h-10'
/>
</div>

<div>
<label className='label'>
<span className='text-base label-text'>Confirm Password</span>
</label>
<input
type='password'
placeholder='Confirm Password'
className='w-full input input-bordered h-10'
/>
</div>

<GenderCheckbox />

<a className='text-sm hover:underline hover:text-blue-600 mt-2 inline-block' href='#'>
Already have an account?
</a>

<div>
<button className='btn btn-block btn-sm mt-2 border border-slate-700'>Sign Up</button>
</div>
</form>
</div>
</div>
);
};
export default SignUp;

// STARTER CODE FOR THE SIGNUP COMPONENT
// import GenderCheckbox from "./GenderCheckbox";

// const SignUp = () => {
// return (
// <div className='flex flex-col items-center justify-center min-w-96 mx-auto'>
// <div className='w-full p-6 rounded-lg shadow-md bg-gray-400 bg-clip-padding backdrop-filter backdrop-blur-lg bg-opacity-0'>
// <h1 className='text-3xl font-semibold text-center text-gray-300'>
// Sign Up <span className='text-blue-500'> ChatApp</span>
// </h1>

// <form>
// <div>
// <label className='label p-2'>
// <span className='text-base label-text'>Full Name</span>
// </label>
// <input type='text' placeholder='John Doe' className='w-full input input-bordered h-10' />
// </div>

// <div>
// <label className='label p-2 '>
// <span className='text-base label-text'>Username</span>
// </label>
// <input type='text' placeholder='johndoe' className='w-full input input-bordered h-10' />
// </div>

// <div>
// <label className='label'>
// <span className='text-base label-text'>Password</span>
// </label>
// <input
// type='password'
// placeholder='Enter Password'
// className='w-full input input-bordered h-10'
// />
// </div>

// <div>
// <label className='label'>
// <span className='text-base label-text'>Confirm Password</span>
// </label>
// <input
// type='password'
// placeholder='Confirm Password'
// className='w-full input input-bordered h-10'
// />
// </div>

// <GenderCheckbox />

// <a className='text-sm hover:underline hover:text-blue-600 mt-2 inline-block' href='#'>
// Already have an account?
// </a>

// <div>
// <button className='btn btn-block btn-sm mt-2 border border-slate-700'>Sign Up</button>
// </div>
// </form>
// </div>
// </div>
// );
// };
// export default SignUp;
9 changes: 9 additions & 0 deletions frontend/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
},
// eslint-disable-next-line no-undef
plugins: [require("daisyui")],
};

0 comments on commit 7aadf4f

Please sign in to comment.