Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e73b392
started creating components
mimmi-eriksson Apr 28, 2025
68f8205
setting up tailwindcss and started styling
mimmi-eriksson Apr 28, 2025
70a5b8f
finished basic styling and added state to like button
mimmi-eriksson Apr 29, 2025
0222be2
added footer content
mimmi-eriksson Apr 29, 2025
4f41164
started on funcion to handle submit of messages
mimmi-eriksson Apr 29, 2025
e987285
added functionality to display a new message card on form submission
mimmi-eriksson Apr 30, 2025
bc88bfb
added a character count below the form input that updates when the us…
mimmi-eriksson Apr 30, 2025
23ff933
added function to convert timestamp to show elapsed time on message …
mimmi-eriksson Apr 30, 2025
cae48a8
small style fix
mimmi-eriksson Apr 30, 2025
60e9cc2
adding fonts and theme
mimmi-eriksson May 2, 2025
88c2d40
fixed text wrap in message card
mimmi-eriksson May 2, 2025
bc22d4e
updating message displaying to match api data
mimmi-eriksson May 8, 2025
fdd1472
fetching messages from api
mimmi-eriksson May 8, 2025
489cd5f
added functionality to post a message and send likes to the api
mimmi-eriksson May 8, 2025
3350218
restructuring and small fixes
mimmi-eriksson May 8, 2025
1bc14d1
added animations to message posting and liking
mimmi-eriksson May 9, 2025
9ac5994
adding error state to show a error message in the UI if an error occu…
mimmi-eriksson May 11, 2025
efd60b7
adding netlify-link
mimmi-eriksson May 11, 2025
7bfa4e4
updated with new api link
mimmi-eriksson May 27, 2025
7310630
updated url and functions to work with my own api
mimmi-eriksson Jun 4, 2025
179eccf
updated message card with tags and buttons to edit and delete message…
mimmi-eriksson Jun 5, 2025
9ed7003
added functions to delete and edit message
mimmi-eriksson Jun 5, 2025
049b562
updated url to deployed
mimmi-eriksson Jun 9, 2025
eb46df3
fixing funcionality to edit message
mimmi-eriksson Jun 9, 2025
e6b2cef
basic styling of sort and filter menu
mimmi-eriksson Jun 9, 2025
43e4b6b
added option to select tags when posting a message
mimmi-eriksson Jun 9, 2025
846a348
fixed function to handle de-selecting a tag
mimmi-eriksson Jun 9, 2025
e753db3
fixed cancel button for editing message and added functionality to po…
mimmi-eriksson Jun 10, 2025
c0d1536
started implementing funcionality that lets the user can click throug…
mimmi-eriksson Jun 10, 2025
4654564
fixed page selector functionality, added functionality to sort and fi…
mimmi-eriksson Jun 10, 2025
b59f0f0
code fix
mimmi-eriksson Jun 10, 2025
3e4f7ea
fixed url issues
mimmi-eriksson Jun 11, 2025
b6aff4d
change date stamp in message card to use date-fns library
mimmi-eriksson Jun 11, 2025
bc1ee3b
adding filter function when clicking a tag on a message card
mimmi-eriksson Jun 11, 2025
e5314c9
adding aria labels to icon buttons
mimmi-eriksson Jun 11, 2025
c838c68
creating a login card component
mimmi-eriksson Jun 11, 2025
0a635f1
added routes to login and signup pages
mimmi-eriksson Jun 11, 2025
7c46878
adding a nav bar and restructuring components
mimmi-eriksson Jun 12, 2025
44f114d
implementing react context to store user in a global state
mimmi-eriksson Jun 13, 2025
dc2142d
restructuring and fixing authorization for adding, editing and deleti…
mimmi-eriksson Jun 13, 2025
7afd1ea
small design and responsiveness fix
mimmi-eriksson Jun 13, 2025
4009640
authorization in posting, deleting and editing
mimmi-eriksson Jun 13, 2025
efae4d9
started building my thoughts page - fetching and displaying thoughts …
mimmi-eriksson Jun 16, 2025
8f96d47
added fetch to display thoughts liked by logged in user
mimmi-eriksson Jun 16, 2025
f11b9d3
changing thoughts route to my-thoughts
mimmi-eriksson Jun 17, 2025
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# Happy Thoughts
Link: https://think-happy.netlify.app/
39 changes: 25 additions & 14 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Happy Thoughts</title>
</head>
<body>
<div id="root"></div>
<script
type="module"
src="./src/main.jsx">
</script>
</body>
</html>

<head>
<meta charset="UTF-8" />
<link
rel="icon"
type="image/x-icon"
href="/favicon.ico"
/>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>Happy Thoughts</title>
</head>

<body>
<div id="root"></div>
<script
type="module"
src="./src/main.jsx"
>
</script>
</body>

</html>
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@
"preview": "vite preview"
},
"dependencies": {
"@tailwindcss/vite": "^4.1.4",
"date-fns": "^4.1.0",
"motion": "^12.10.4",
"react": "^19.0.0",
"react-dom": "^19.0.0"
"react-dom": "^19.0.0",
"react-router": "^7.6.2",
"react-router-dom": "^7.6.2",
"tailwindcss": "^4.1.4"
},
"devDependencies": {
"@eslint/js": "^9.21.0",
Expand Down
44 changes: 44 additions & 0 deletions public/assets/github-btn.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions public/assets/linkedin-btn.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon.ico
Binary file not shown.
1 change: 0 additions & 1 deletion public/vite.svg

This file was deleted.

42 changes: 40 additions & 2 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,43 @@
export const App = () => {
import { BrowserRouter, Routes, Route } from 'react-router'
import { AuthProvider } from './context/AuthContext'
import NavBar from "./sections/NavBar"
import Footer from "./sections/Footer"
import Home from './pages/Home'
import LogIn from './pages/LogIn'
import Register from './pages/Register'
import MyThoughts from './pages/MyThoughts'
import NotFound from './pages/NotFound'
import ProtectedPage from './pages/ProtectedPage'

const App = () => {
return (
<h1>Happy Thoughts</h1>
<BrowserRouter>
<AuthProvider>
<div className="flex flex-col min-h-screen">
<NavBar />
<div
className="w-full max-w-md px-4 min-[375px]:px-10 mx-auto"
>
<Routes>
<Route path='/' element={<Home />} />
<Route path='/login' element={<LogIn />} />
<Route path='/register' element={<Register />} />
<Route
path='/mythoughts'
element={
<ProtectedPage>
<MyThoughts />
</ProtectedPage>
}
/>
<Route path='*' element={<NotFound />} />
</Routes>
</div>
<Footer />
</div>
</AuthProvider>
</BrowserRouter>
)
}

export default App
16 changes: 16 additions & 0 deletions src/components/ArrowButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const ArrowButton = ({ icon, isActive, onClick, ariaLabel }) => {
return (
<button
className={`bg-[#ffadad] w-10 aspect-square rounded-full focus:outline-2 focus:outline-(--color-primary) ${isActive ? 'hover:bg-(--color-primary) cursor-pointer' : 'opacity-50'}`}
type="button"
onClick={onClick}
disabled={!isActive}
aria-label={ariaLabel}
>
{icon}
</button>
)
}

export default ArrowButton

15 changes: 15 additions & 0 deletions src/components/CancelButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const CancelButton = ({ onClick }) => {
return (
<button
className="bg-[#ffadad] rounded-full focus:outline-2 focus:outline-(--color-primary) py-2 px-5 text-sm cursor-pointer"
type="button"
onClick={onClick}
>
<p>
Cancel
</p>
</button >
)
}

export default CancelButton
9 changes: 9 additions & 0 deletions src/components/Error.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const Error = ({ text }) => {
return (
<div className="bg-white border border-black border-solid shadow-[10px_10px] shadow-black p-5 text-center text-red-500">
<p>{text}</p>
</div>
)
}

export default Error
7 changes: 7 additions & 0 deletions src/components/FilterOption.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const FilterOption = ({ value }) => {
return (
<option value={value}>{value}</option>
)
}

export default FilterOption
14 changes: 14 additions & 0 deletions src/components/LikeButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const LikeButton = ({ likes, onLike }) => {
return (
<button
className={`bg-(--color-secondary) ${likes > 0 && 'bg-[#ffadad]'} rounded-full focus:outline-2 focus:outline-(--color-primary) p-2 transition duration-300 hover:scale-115 active:scale-90 cursor-pointer`}
type="button"
onClick={onLike}
aria-label="Like thought"
>
❤️
</button>
)
}

export default LikeButton
66 changes: 66 additions & 0 deletions src/components/ListControls.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { useState } from "react"
import RadioOption from "./RadioOption"
import FilterOption from "./FilterOption"

const ListControls = ({ sortBy, filterOn, onSort, onFilter }) => {
const [sorting, setSorting] = useState(sortBy)
const [filter, setFilter] = useState(filterOn)

const sortOptions = [
{ id: "createdAt", label: "Recent" },
{ id: "hearts", label: "Popular" }
]
const filterOptions = ["all", "travel", "food", "family", "friends", "humor", "nature", "wellness", "home", "entertainment", "work", "other"]

const onSortingChange = (event) => {
setSorting(event.target.value)
onSort(event.target.value)
}

const onFilterChange = (event) => {
setFilter(event.target.value)
onFilter(event.target.value)
}

return (
<article
className="px-5 text-sm"
>
<form className="flex flex-col gap-3">

<fieldset className="flex items-center gap-8">
<legend className="float-left" >Sort on:</legend>
<div className="flex gap-5">
{sortOptions.map(({ id, label }) => (
<RadioOption
key={id}
radioGroup="sortBy"
id={id}
label={label}
isChecked={sorting === id}
onChange={onSortingChange}
/>
))}
</div>
</fieldset>

<div className="flex items-center gap-6">
<label className="" htmlFor="tags">Filter on:</label>
<select
className="w-45 bg-[#ffeded] border border-(--color-accent) rounded-full focus:outline-2 focus:outline-(--color-primary) p-1 cursor-pointer"
name="tags"
id="tags"
value={filter}
onChange={onFilterChange}
>
{filterOptions.map((option) => (
<FilterOption key={option} value={option} />
))}
</select>
</div>
</form>
</article>
)
}

export default ListControls
10 changes: 10 additions & 0 deletions src/components/Loader.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const Loader = () => {
return (
<div className="flex flex-col gap-2 items-center py-10">
<div className="w-12 h-12 rounded-full border-7 border-(--color-accent) border-t-(--color-primary) animate-spin"></div>
<p>Loading thoughts...</p>
</div>
)
}

export default Loader
Loading