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

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
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.