Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" href="/favicon-dark.ico" media="(prefers-color-scheme: light)">
<link rel="icon" href="/favicon.ico" media="(prefers-color-scheme: dark)">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>client</title>
<title>CodeFolio</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
<script>
const theme = localStorage.getItem("theme") || "light";
document.documentElement.setAttribute("data-theme", theme);
</script>
</body>
</html>
1,199 changes: 1,087 additions & 112 deletions client/package-lock.json

Large diffs are not rendered by default.

14 changes: 10 additions & 4 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@
"preview": "vite preview"
},
"dependencies": {
"react": "^19.2.4",
"react-dom": "^19.2.4",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@mui/icons-material": "^9.0.0",
"@mui/material": "^9.0.0",
"@tailwindcss/vite": "^4.2.2",
"react": "^19.2.5",
"react-dom": "^19.2.5",
"react-router": "^7.14.0",
"react-router-dom": "^7.14.0"
},
"devDependencies": {
Expand All @@ -23,9 +29,9 @@
"eslint": "^9.39.4",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.4.0",
"globals": "^17.5.0",
"postcss": "^8.5.9",
"tailwindcss": "^4.2.2",
"vite": "^8.0.4"
"vite": "^8.0.8"
}
}
1 change: 0 additions & 1 deletion client/src/App.css

This file was deleted.

41 changes: 36 additions & 5 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,42 @@
import './App.css'
import { useRoutes } from "react-router"
import BodyLayout from "./layouts/BodyLayout"
import Navbar from "./components/layout/Navbar"
import Footer from "./components/layout/Footer"
import Home from "./pages/Home"
import Login from "./pages/Login"
import SignUp from "./pages/SignUp"
import UserProfile from "./pages/UserProfile"

function App() {

return (
<>
</>
)
let element = useRoutes([
{
path: '/',
element: <Home />
},
{
path: '/login',
element: <Login />
},
{
path: '/signup',
element: <SignUp />
},
{
path: '/profile',
element: <UserProfile />
}
])

return (
<div className="min-h-screen flex flex-col bg-app-bg dark:bg-app-bg">
<Navbar />
<main className="flex-1 w-full max-w-9/10 mx-auto px-4 sm:px-6 lg:px-8 py-4">
<BodyLayout element={element} />
</main>
<Footer />
</div>
)
}

export default App
16 changes: 16 additions & 0 deletions client/src/components/layout/Footer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

const Footer = () => {
return (
<>
<footer className="border-t border-border bg-app-bg">
<div className="max-w-7xl mx-auto px-4 py-8">
<div className="text-center text-sm text-app-muted">
© {new Date().getFullYear()} CodeFolio. All rights reserved.
</div>
</div>
</footer>
</>
)
}

export default Footer
32 changes: 32 additions & 0 deletions client/src/components/layout/LeftSidebar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import SideMenuItem from "../ui/SideMenuItem"

// icons
import ArticleIcon from '@mui/icons-material/Article';
import GroupsIcon from '@mui/icons-material/Groups';
import Person2Icon from '@mui/icons-material/Person2';
import BookmarkIcon from '@mui/icons-material/Bookmark';
import WifiTetheringIcon from '@mui/icons-material/WifiTethering';

const LeftSidebar = () => {
const menu = [
{ text: 'Projects', icon: <ArticleIcon />, to: '/projects' },
{ text: 'Community', icon: <GroupsIcon />, to: '/community' },
{ text: 'Network', icon: <WifiTetheringIcon />, to: '/network' },
{ text: 'Bookmarks', icon: <BookmarkIcon />, to: '/bookmarks' },
]

return (
<aside>
{menu.map((item) => (
<SideMenuItem
key={item.text}
icon={item.icon}
text={item.text}
to={item.to}
/>
))}
</aside>
)
}

export default LeftSidebar
56 changes: 56 additions & 0 deletions client/src/components/layout/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useEffect, useState } from 'react';
import { Link } from 'react-router';
import { Avatar } from '@mui/material';

// Components
import SearchBar from '../ui/SearchBar';

// Icons
import DarkModeIcon from '@mui/icons-material/DarkMode';
import LightModeOutlinedIcon from '@mui/icons-material/LightModeOutlined';

// Images
import Codefolio from '../../assets/logo/codefolio.svg'
import CodefolioDark from '../../assets/logo/codefolio-dark.svg'

const Navbar = () => {
const [theme, setTheme] = useState(() => {
return localStorage.getItem("theme") || "light"
})

useEffect(() => {
localStorage.setItem("theme", theme);
document.documentElement.setAttribute("data-theme", theme)
}, [theme])

return (
<div className="w-full border-b border-border">
<div className="max-w-9/10 mx-auto flex items-center justify-between h-25 px-4 sm:px-6 lg:px-8">

{/* Left */}
<div className='w-40 sm:w-52 lg:w-60'>
{theme === "light"
? <Link to="/"><img src={CodefolioDark} alt="Codefolio" className="w-10"/></Link>
: <Link to="/"><img src={Codefolio} alt="Codefolio" className="w-10"/></Link>
}
</div>

{/* Search */}
<div className="hidden md:block flex-1 max-w-md">
<SearchBar />
</div>

{/* Right */}
<div className='flex items-center justify-end gap-4 w-40 sm:w-52 lg:w-60'>
<button onClick={() => setTheme((prev) => (prev === "light" ? "dark" : "light"))}>
{theme === "light" ? <DarkModeIcon /> : <LightModeOutlinedIcon />}
</button>

<Avatar className="bg-black">MA</Avatar>
</div>
</div>
</div>
)
}

export default Navbar
11 changes: 11 additions & 0 deletions client/src/components/layout/RightSidebar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import TopProjects from "../ui/TopProjects"

const RightSidebar = () => {
return (
<aside>
<TopProjects />
</aside>
)
}

export default RightSidebar
32 changes: 32 additions & 0 deletions client/src/components/ui/SearchBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useState } from 'react';
import SearchIcon from '@mui/icons-material/Search';

const SearchBar = () => {
const [searchValue, setSearchValue] = useState('')

const handleChange = (event) => {
setSearchValue(event.target.value)
}

return (
<div className="search-bar">
<select name="" id="">
<option value="projects">Projects</option>
<option value="posts">Posts</option>
<option value="people">People</option>
</select>
<input
type="text"
name="searchValue"
id="searchValue"
placeholder="Search"
className="w-full"
value={searchValue}
onChange={handleChange}
/>
<SearchIcon />
</div>
)
}

export default SearchBar
12 changes: 12 additions & 0 deletions client/src/components/ui/SideMenuItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Link } from "react-router"

const SideMenuItem = ({ icon, text, to}) => {
return (
<Link className="menu-item" to={to}>
{icon}
<span>{text}</span>
</Link>
)
}

export default SideMenuItem
28 changes: 28 additions & 0 deletions client/src/components/ui/TopProjects.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

const TopProjects = (
{ topProjects = [ "TechQuick", "BuildMySupra", "Unearthed", "Crewmates" ],
topTags = [ "python", "react", "express", "html", "css"] }
) => {

return (
<div className="flex flex-col items-end text-right">
<div className="w-full flex flex-col gap-2 mb-3 items-end text-right pb-2 border-b-2 border-text">
<h4 className="heading-sm">Top Projects</h4>
<div>
{topProjects.map((project) => (
<div key={project} className="mb-2">
{project}
</div>
))}
</div>
</div>
<div className="w-fit flex flex-row flex-wrap gap-x-2 items-end justify-end text-muted">
{topTags.map((tag) => (
<span key={tag} className="hover:scale-105">#{tag}</span>
))}
</div>
</div>
)
}

export default TopProjects
Loading