From 860d60b894cb4165425292ec2a776ad2231e2a36 Mon Sep 17 00:00:00 2001
From: JosteinRuen <99617155+JosteinRuen@users.noreply.github.com>
Date: Thu, 3 Oct 2024 12:40:18 +0200
Subject: [PATCH 1/4] Header, sidebar almost done
---
.gitignore | 24 +
README.md | 66 +-
STYLE_GUIDE.md | 8 -
eslint.config.js | 38 +
index.html | 13 +
package-lock.json | 4525 +++++++++++++++++++
package.json | 29 +
public/vite.svg | 1 +
src/App.css | 42 +
src/App.jsx | 84 +
src/Components/Header.css | 40 +
src/Components/Header.jsx | 36 +
src/Components/Posts.jsx | 0
src/Components/Profile.jsx | 23 +
src/Components/Sidebar.jsx | 30 +
{_assets => src/assets}/dashboard.png | Bin
{_assets => src/assets}/home-icon-svg.md | 0
src/assets/home-icon.svg | 3 +
{_assets => src/assets}/profile-icon-svg.md | 0
src/assets/profile-icon.svg | 11 +
{_assets => src/assets}/profile.png | Bin
src/assets/react.svg | 1 +
{_assets => src/assets}/title-header-svg.md | 0
src/assets/title-header.svg | 13 +
src/index.css | 0
src/main.jsx | 15 +
vite.config.js | 7 +
27 files changed, 4940 insertions(+), 69 deletions(-)
create mode 100644 .gitignore
delete mode 100644 STYLE_GUIDE.md
create mode 100644 eslint.config.js
create mode 100644 index.html
create mode 100644 package-lock.json
create mode 100644 package.json
create mode 100644 public/vite.svg
create mode 100644 src/App.css
create mode 100644 src/App.jsx
create mode 100644 src/Components/Header.css
create mode 100644 src/Components/Header.jsx
create mode 100644 src/Components/Posts.jsx
create mode 100644 src/Components/Profile.jsx
create mode 100644 src/Components/Sidebar.jsx
rename {_assets => src/assets}/dashboard.png (100%)
rename {_assets => src/assets}/home-icon-svg.md (100%)
create mode 100644 src/assets/home-icon.svg
rename {_assets => src/assets}/profile-icon-svg.md (100%)
create mode 100644 src/assets/profile-icon.svg
rename {_assets => src/assets}/profile.png (100%)
create mode 100644 src/assets/react.svg
rename {_assets => src/assets}/title-header-svg.md (100%)
create mode 100644 src/assets/title-header.svg
create mode 100644 src/index.css
create mode 100644 src/main.jsx
create mode 100644 vite.config.js
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..a547bf36d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/README.md b/README.md
index c7ea45f8a..f768e33fc 100644
--- a/README.md
+++ b/README.md
@@ -1,64 +1,8 @@
-# React Cohort Dashboard Challenge
+# React + Vite
-## Learning Objectives
-- Use ReactJS to build an implementation of a provided application design
-- Use HTTP requests to interact with a RESTful API
-- Use routing to allow navigation between pages in a React app
+This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
-In this challenge, you'll create a social media style post feed. There is no boilerplate code provided - you'll be building this from scratch using the designs and specifications provided.
+Currently, two official plugins are available:
-## Setting up React with Vite
-- Fork and clone the repository
-
-\-------------------------------------------------------------------------------------------------------
-
-MAKE SURE YOU HAVE READ THE ENTIRE README BEFORE RUNNING THESE COMMANDS
-
-\-------------------------------------------------------------------------------------------------------
-
-- In the project root directory, run `npm create vite@latest . -- --template react`
- - Be 100% sure that your current directory is this repo project root directory, as the command will HARD DELETE all existing files and folders in the current directory. This cannot be undone or restored easily.
-- When it asks you: `? Current directory is not empty. Remove existing files and continue? ยป (y/N)`
- - re-read the warning above to check you are in the correct directory
- - type the letter `y` and press `Enter`
- - This will completely replace this existing repo on your machine with the Vite React project scaffold - this is expected
- - To reference the original documentation/images provided in this repo, just go to the original online repo on the Boolean UK GitHub account
-- Run `npm install`
-- `npm run dev` to run the application
-
-The steps above will create a fresh React app using Vite. From this point on, it's up to you to decide how you want to structure your code. Try to stay organised :)
-
-## Instructions
-
-[Implement this design](./_assets/dashboard.png) using, as a minimum, the below listed technologies. Note: you may need to open the file directly on your machine to view it properly.
-
-- ReactJS
-- React Router DOM version 6.4 or above (Run `npm install react-router-dom` to install this)
-- A RESTful API
-
-[Use this REST API](https://boolean-uk-api-server.fly.dev/api-docs/#/post) as your data source. Use the **post** endpoints, which contains routes for posts and comments. Each of these routes has GET, POST, PUT and DELETE methods available. Post and comment authors are linked to the contacts retrieved from the **contact** endpoints via a `contactId` property, which will allow you to retrieve information about post and comment authors.
-
-## Core Requirements
-
-- Everything that *can* be its own component, *should* be its own component. You **must** provide evidence of planning your components by creating a component tree diagram. Include your diagram as a file in the root directory of this repository.
-- Users should be able to create a new post. The new post should be displayed at the top of the post feed.
-- Users should be able to comment on existing posts.
-- Posts and comments should show the initials of the author in a coloured circle.
-- Clicking a posts title (under the author name) should take the user to a separate route that shows only that post and all of its comments. You **must** use a route for this, not an array filter.
-- You must use [this style guide](./STYLE_GUIDE.md) to implement the colour scheme.
-- The layout does not need to be mobile responsive, nor does it need to be pixel perfect. Get as close as you can, but your main focus should be on React - not CSS.
-
-## Extension Requirements
-
-- Use the Context API to reduce prop drilling of state
-- Only 3 comments should be visible on a post; if a post has more than 3 comments, the `See previous comments` link should expand the list of comments to display all of them.
-- Clicking on a post / comment authors name or initials, the user initials in the top right of the app, or the `Profile` link in the left navigation menu should take the user to [this Profile screen](./_assets/profile.png).
- - Use the contact with an ID of 1 to emulate the currently logged in user. This is the user you should use when clicking the top right initials or the Profile menu item directly.
- - The fields should be automatically populated with the correct data when loading any user profile.
- - Note that the design provided only shows example form fields to demonstrate roughly how the design of the page should look, you should inspect what data is available on a Contact entity to decide which fields you'll actually create.
-- You should be able to update all of the users information.
-- Posts and comments should be able to be updated and deleted.
-
-## Advice
-
-Break this project down into smaller, individual tasks. You could use a simple todo list, a project management board like Trello, anything you like. Not only will this reduce overwhelm and provide you with a clear path forward, it'll also ensure you have understood and accounted for every requirement.
+- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
+- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
diff --git a/STYLE_GUIDE.md b/STYLE_GUIDE.md
deleted file mode 100644
index 0a34e97b8..000000000
--- a/STYLE_GUIDE.md
+++ /dev/null
@@ -1,8 +0,0 @@
-- Header background, button & font colour: #000046
-- Form input background colour: #e6ebf5
-- Button hover colour: #64dc78
-- Post title colour: #64648c
-- Body background colour: #F0F5FA
-- [Header logo SVG](./_assets/title-header-svg.md)
-- [Home icon SVG](./_assets/home-icon-svg.md)
-- [Profile icon SVG](./_assets/profile-icon-svg.md)
\ No newline at end of file
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 000000000..238d2e4e6
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,38 @@
+import js from '@eslint/js'
+import globals from 'globals'
+import react from 'eslint-plugin-react'
+import reactHooks from 'eslint-plugin-react-hooks'
+import reactRefresh from 'eslint-plugin-react-refresh'
+
+export default [
+ { ignores: ['dist'] },
+ {
+ files: ['**/*.{js,jsx}'],
+ languageOptions: {
+ ecmaVersion: 2020,
+ globals: globals.browser,
+ parserOptions: {
+ ecmaVersion: 'latest',
+ ecmaFeatures: { jsx: true },
+ sourceType: 'module',
+ },
+ },
+ settings: { react: { version: '18.3' } },
+ plugins: {
+ react,
+ 'react-hooks': reactHooks,
+ 'react-refresh': reactRefresh,
+ },
+ rules: {
+ ...js.configs.recommended.rules,
+ ...react.configs.recommended.rules,
+ ...react.configs['jsx-runtime'].rules,
+ ...reactHooks.configs.recommended.rules,
+ 'react/jsx-no-target-blank': 'off',
+ 'react-refresh/only-export-components': [
+ 'warn',
+ { allowConstantExport: true },
+ ],
+ },
+ },
+]
diff --git a/index.html b/index.html
new file mode 100644
index 000000000..0c589eccd
--- /dev/null
+++ b/index.html
@@ -0,0 +1,13 @@
+
+
+
+
-
-
-
-
-
-
-
- } />
-
-
-
-
+
+
-
- >
- )
+
+ );
}
-export default App
+export default App;
\ No newline at end of file
diff --git a/src/Components/CommentList.jsx b/src/Components/CommentList.jsx
new file mode 100644
index 000000000..155e14ed8
--- /dev/null
+++ b/src/Components/CommentList.jsx
@@ -0,0 +1,55 @@
+import { useState, useEffect, useContext } from "react";
+import { AppContext } from "../App";
+import "./Styling/CommentList.css";
+import NewCommentForm from "./NewCommentForm";
+
+function getInitials(firstName, lastName) {
+ return `${firstName[0]}${lastName[0]}`.toUpperCase();
+ }
+
+function CommentList({ postId }) {
+ const [comments, setComments] = useState([]);
+ const { friendList } = useContext(AppContext);
+
+ useEffect(() => {
+ const fetchComments = async () => {
+ try {
+ const response = await fetch(`https://boolean-uk-api-server.fly.dev/josteinruen/post/${postId}/comment`);
+ const data = await response.json();
+ setComments(data);
+ } catch (error) {
+ console.error('Error fetching comments:', error);
+ }
+ };
+
+ fetchComments();
+ }, [postId]);
+
+ const getCommenter = (contactId) => {
+ return friendList.find(friend => friend.id === contactId);
+ };
+
+ return (
+
+ {comments.length > 0 ? (
+ comments.map(comment => {
+ const commenter = getCommenter(comment.contactId);
+ const initials = commenter ? getInitials(commenter.firstName, commenter.lastName) : "NA";
+ return (
+
+
+ {initials}
+
+
{commenter ? `${commenter.firstName} ${commenter.lastName}` : "Unknown"} : {comment.content}
+
+ );
+ })
+ ) : (
+
No comments available.
+ )}
+
+
+ );
+}
+
+export default CommentList;
\ No newline at end of file
diff --git a/src/Components/Header.jsx b/src/Components/Header.jsx
index 7ce2956e5..e91b7a2be 100644
--- a/src/Components/Header.jsx
+++ b/src/Components/Header.jsx
@@ -2,7 +2,7 @@ import { useContext } from "react";
import { AppContext } from "../App";
import titleHeaderIcon from "../assets/title-header.svg";
import profileIcon from "../assets/profile-icon.svg";
-import "./Header.css";
+import "./Styling/Header.css";
function getInitials(firstName, lastName) {
return `${firstName[0]}${lastName[0]}`.toUpperCase();
diff --git a/src/Components/NewCommentForm.jsx b/src/Components/NewCommentForm.jsx
new file mode 100644
index 000000000..fd3faab65
--- /dev/null
+++ b/src/Components/NewCommentForm.jsx
@@ -0,0 +1,61 @@
+import { useState, useContext } from "react";
+import { AppContext } from "../App";
+import "./Styling/NewCommentForm.css";
+
+function NewCommentForm({ postId }) {
+ const { user, setPosts } = useContext(AppContext);
+ const [content, setContent] = useState("");
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ if (!content) return;
+
+ const newComment = {
+ content,
+ contactId: user.id,
+ postId,
+ createdAt: new Date().toISOString(),
+ };
+
+ try {
+ const response = await fetch(`https://boolean-uk-api-server.fly.dev/josteinruen/post/${postId}/comment`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(newComment),
+ });
+
+ if (response.ok) {
+ const createdComment = await response.json();
+ setPosts((prevPosts) =>
+ prevPosts.map((post) =>
+ post.id === postId
+ ? { ...post, comments: [createdComment, ...post.comments] }
+ : post
+ )
+ );
+ setContent("");
+ } else {
+ console.error('Error creating comment:', response.statusText);
+ }
+ } catch (error) {
+ console.error('Error creating comment:', error);
+ }
+ };
+
+ return (
+
+ );
+}
+
+export default NewCommentForm;
\ No newline at end of file
diff --git a/src/Components/NewPostForm.jsx b/src/Components/NewPostForm.jsx
new file mode 100644
index 000000000..b75cb5317
--- /dev/null
+++ b/src/Components/NewPostForm.jsx
@@ -0,0 +1,67 @@
+import { useState, useContext } from "react";
+import { AppContext } from "../App";
+import "./Styling/NewPostForm.css";
+
+function NewPostForm() {
+ const { user, setPosts } = useContext(AppContext)
+ const [title, setTitle] = useState("")
+ const [content, setContent] = useState("")
+
+ const handleSubmit = async (e) => {
+ e.preventDefault()
+ if (!title || !content) return
+
+ const newPost = {
+ title,
+ content,
+ contactId: user.id,
+ createdAt: new Date().toISOString(),
+ comments: [],
+ };
+
+ try {
+ const response = await fetch('https://boolean-uk-api-server.fly.dev/josteinruen/post', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(newPost),
+ })
+
+ if (response.ok) {
+ const createdPost = await response.json()
+ setPosts((prevPosts) => [createdPost, ...prevPosts])
+ setTitle("");
+ setContent("");
+ } else {
+ console.error('Error creating post:', response.statusText)
+ }
+ } catch (error) {
+ console.error('Error creating post:', error)
+ }
+ }
+
+ return (
+
+ Create New Post
+
+ Title
+ setTitle(e.target.value)}
+ />
+
+
+ Content
+ setContent(e.target.value)}
+ />
+
+ Create Post
+
+ )
+}
+
+export default NewPostForm;
\ No newline at end of file
diff --git a/src/Components/PostList.jsx b/src/Components/PostList.jsx
new file mode 100644
index 000000000..aa00e0043
--- /dev/null
+++ b/src/Components/PostList.jsx
@@ -0,0 +1,21 @@
+import { useContext } from "react";
+import { AppContext } from "../App";
+import PostListItem from "./PostListItem";
+import "./Styling/PostList.css";
+
+function PostList() {
+ const { posts } = useContext(AppContext);
+ console.log('posts:',posts);
+
+ return (
+
+ {posts && posts.length > 0 ? (
+ posts.map(post =>
)
+ ) : (
+
No posts available.
+ )}
+
+ );
+}
+
+export default PostList;
\ No newline at end of file
diff --git a/src/Components/PostListItem.jsx b/src/Components/PostListItem.jsx
new file mode 100644
index 000000000..df1bb574c
--- /dev/null
+++ b/src/Components/PostListItem.jsx
@@ -0,0 +1,38 @@
+import { useContext } from "react";
+import { AppContext } from "../App";
+import CommentList from "./CommentList";
+import "./Styling/PostListItem.css";
+
+function getInitials(firstName, lastName) {
+ return `${firstName[0]}${lastName[0]}`.toUpperCase();
+}
+
+function PostListItem({ post }) {
+ const { friendList } = useContext(AppContext);
+
+ if (!friendList) {
+ return null;
+ }
+
+ const postAuthor = friendList.find(friend => friend.id === post.contactId);
+ const initials = postAuthor ? getInitials(postAuthor.firstName, postAuthor.lastName) : "NA";
+ const authorName = postAuthor ? `${postAuthor.firstName} ${postAuthor.lastName}` : "Unknown";
+
+ return (
+
+
+
+ {initials}
+
+
{authorName}
+
+
+
{post.title}
+
{post.content}
+
+
+
+ );
+}
+
+export default PostListItem;
\ No newline at end of file
diff --git a/src/Components/Posts.jsx b/src/Components/Posts.jsx
index e69de29bb..a4a5d24d2 100644
--- a/src/Components/Posts.jsx
+++ b/src/Components/Posts.jsx
@@ -0,0 +1,18 @@
+import { useContext } from "react";
+import { AppContext } from "../App";
+import PostList from "./PostList";
+import NewPostForm from "./NewPostForm";
+
+function Posts() {
+ const { posts } = useContext(AppContext);
+
+ return (
+
+ );
+}
+
+export default Posts;
\ No newline at end of file
diff --git a/src/Components/Sidebar.jsx b/src/Components/Sidebar.jsx
index 1e8b06c11..c10a96beb 100644
--- a/src/Components/Sidebar.jsx
+++ b/src/Components/Sidebar.jsx
@@ -1,30 +1,28 @@
import { Link } from "react-router-dom";
import profileIcon from "../assets/profile-icon.svg";
import homeIcon from "../assets/home-icon.svg";
-
+import "./Styling/Sidebar.css";
function Sidebar() {
return (
- <>
-
- Sidebar Element
-
-
-
+
+ Sidebar Element
+
+
+
- Home
-
-
-
-
-
- Profile
-
-
-
-
- >
+ Home
+
+
+
+
+
+ Profile
+
+
+
+
);
}
-export default Sidebar
\ No newline at end of file
+export default Sidebar;
\ No newline at end of file
diff --git a/src/App.css b/src/Components/Styling/App.css
similarity index 78%
rename from src/App.css
rename to src/Components/Styling/App.css
index b9d355df2..781b24c2d 100644
--- a/src/App.css
+++ b/src/Components/Styling/App.css
@@ -1,10 +1,15 @@
#root {
+ display: flex;
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
+ background-color: #F0F5FA; /* Body background colour */
+}
+.main-content {
+ flex: 1;
+ margin-left: 200px; /* Adjust based on sidebar width */
}
-
.logo {
height: 6em;
padding: 1.5em;
@@ -17,7 +22,6 @@
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
-
@keyframes logo-spin {
from {
transform: rotate(0deg);
@@ -26,17 +30,14 @@
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;
-}
+}
\ No newline at end of file
diff --git a/src/Components/Styling/CommentList.css b/src/Components/Styling/CommentList.css
new file mode 100644
index 000000000..3988a19f2
--- /dev/null
+++ b/src/Components/Styling/CommentList.css
@@ -0,0 +1,30 @@
+.comment-list {
+ display: block;
+ margin-top: 1rem;
+ padding-left: 1rem;
+ border-left: 2px solid #dee2e6;
+ }
+
+ .comment {
+ display: flex;
+ align-items: center;
+ margin-bottom: 0.5rem;
+ }
+
+ .comment-author-initials {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 30px;
+ height: 30px;
+ border-radius: 50%;
+ background-color: #64648c;
+ color: white;
+ font-size: 0.875rem;
+ font-weight: bold;
+ margin-right: 0.5rem;
+ }
+
+ .comment p {
+ margin: 0;
+ }
\ No newline at end of file
diff --git a/src/Components/Header.css b/src/Components/Styling/Header.css
similarity index 83%
rename from src/Components/Header.css
rename to src/Components/Styling/Header.css
index 9d95c6f07..aa51f67bd 100644
--- a/src/Components/Header.css
+++ b/src/Components/Styling/Header.css
@@ -3,7 +3,7 @@
justify-content: space-between;
align-items: center;
padding: 1rem;
- background-color: #f8f9fa;
+ background-color: #000046;
border-bottom: 1px solid #dee2e6;
}
@@ -16,6 +16,11 @@
height: 40px;
}
+ .header-title {
+ color: white; /* Set text color to white */
+ margin-left: 0.5rem;
+ }
+
.header-right {
display: flex;
align-items: center;
diff --git a/src/Components/Styling/NewCommentForm.css b/src/Components/Styling/NewCommentForm.css
new file mode 100644
index 000000000..f4c29a871
--- /dev/null
+++ b/src/Components/Styling/NewCommentForm.css
@@ -0,0 +1,37 @@
+.new-comment-form {
+ margin-top: 1rem;
+ padding: 1rem;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ background-color: #f8f9fa;
+ }
+
+ .new-comment-form div {
+ margin-bottom: 1rem;
+ }
+
+ .new-comment-form label {
+ display: block;
+ margin-bottom: 0.5rem;
+ font-weight: bold;
+ }
+
+ .new-comment-form textarea {
+ width: 100%;
+ padding: 0.5rem;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ }
+
+ .new-comment-form button {
+ padding: 0.5rem 1rem;
+ border: none;
+ border-radius: 4px;
+ background-color: #007bff;
+ color: white;
+ cursor: pointer;
+ }
+
+ .new-comment-form button:hover {
+ background-color: #0056b3;
+ }
\ No newline at end of file
diff --git a/src/Components/Styling/NewPostForm.css b/src/Components/Styling/NewPostForm.css
new file mode 100644
index 000000000..63aaef235
--- /dev/null
+++ b/src/Components/Styling/NewPostForm.css
@@ -0,0 +1,42 @@
+.new-post-form {
+ margin-bottom: 2rem;
+ padding: 1rem;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ background-color: #f8f9fa;
+ }
+
+ .new-post-form h2 {
+ margin-top: 0;
+ }
+
+ .new-post-form div {
+ margin-bottom: 1rem;
+ }
+
+ .new-post-form label {
+ display: block;
+ margin-bottom: 0.5rem;
+ font-weight: bold;
+ }
+
+ .new-post-form input,
+ .new-post-form textarea {
+ width: 100%;
+ padding: 0.5rem;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ }
+
+ .new-post-form button {
+ padding: 0.5rem 1rem;
+ border: none;
+ border-radius: 4px;
+ background-color: #007bff;
+ color: white;
+ cursor: pointer;
+ }
+
+ .new-post-form button:hover {
+ background-color: #0056b3;
+ }
\ No newline at end of file
diff --git a/src/Components/Styling/PostList.css b/src/Components/Styling/PostList.css
new file mode 100644
index 000000000..5bc7e66d5
--- /dev/null
+++ b/src/Components/Styling/PostList.css
@@ -0,0 +1,3 @@
+.post-list {
+ padding: 1rem;
+ }
\ No newline at end of file
diff --git a/src/Components/Styling/PostListItem.css b/src/Components/Styling/PostListItem.css
new file mode 100644
index 000000000..a483631fe
--- /dev/null
+++ b/src/Components/Styling/PostListItem.css
@@ -0,0 +1,45 @@
+.post-list-item {
+ display: block;
+ padding: 1rem;
+ border-bottom: 1px solid #dee2e6;
+ }
+
+ .post-author {
+ display: flex;
+ align-items: center;
+ margin-bottom: 1rem;
+ }
+
+ .post-author-initials {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background-color: #64648c;
+ color: white;
+ font-size: 1rem;
+ font-weight: bold;
+ margin-right: 0.5rem; /* Adjust margin to control spacing */
+ }
+
+ .post-author-name {
+ font-size: 1rem;
+ font-weight: bold;
+ color: #000046; /* Font colour */
+ }
+
+ .post-content {
+ margin-bottom: 1rem;
+ }
+
+ .post-content h3 {
+ margin: 0;
+ font-size: 1.25rem;
+ color: #64648c; /* Post title colour */
+ }
+
+ .post-content p {
+ margin: 0.5rem 0 0;
+ }
\ No newline at end of file
diff --git a/src/Components/Styling/Sidebar.css b/src/Components/Styling/Sidebar.css
new file mode 100644
index 000000000..c4e6ec9ac
--- /dev/null
+++ b/src/Components/Styling/Sidebar.css
@@ -0,0 +1,32 @@
+.sidebar {
+ width: 200px;
+ height: 100vh;
+ position: fixed;
+ top: 0;
+ left: 0;
+ background-color: #f8f9fa;
+ border-right: 1px solid #dee2e6;
+ padding: 1rem;
+ box-sizing: border-box;
+ }
+
+ .sidebar ul {
+ list-style: none;
+ padding: 0;
+ }
+
+ .sidebar-link {
+ display: flex;
+ align-items: center;
+ padding: 0.5rem 0;
+ text-decoration: none;
+ color: #333;
+ }
+
+ .sidebar-icon {
+ margin-right: 0.5rem;
+ }
+
+ .sidebar-text {
+ font-size: 1rem;
+ }
\ No newline at end of file
diff --git a/src/assets/profile-icon.svg b/src/assets/profile-icon.svg
index 2c1edde0c..b3e0339a2 100644
--- a/src/assets/profile-icon.svg
+++ b/src/assets/profile-icon.svg
@@ -7,5 +7,6 @@
>
+ d="M7.6 31.25C9.7 29.7833 11.7833 28.6583 13.85 27.875C15.9167 27.0917 18.1333 26.7 20.5 26.7C22.8667 26.7 25.0917 27.0917 27.175 27.875C29.2583 28.6583 31.35 29.7833 33.45 31.25C34.9167 29.45 35.9583 27.6333 36.575 25.8C37.1917 23.9667 37.5 22.0333 37.5 20C37.5 15.1667 35.875 11.125 32.625 7.875C29.375 4.625 25.3333 3 20.5 3C15.6667 3 11.625 4.625 8.375 7.875C5.125 11.125 3.5 15.1667 3.5 20C3.5 22.0333 3.81667 23.9667 4.45 25.8C5.08333 27.6333 6.13333 29.45 7.6 31.25ZM20.5 21.5C18.5667 21.5 16.9417 20.8417 15.625 19.525C14.3083 18.2083 13.65 16.5833 13.65 14.65C13.65 12.7167 14.3083 11.0917 15.625 9.775C16.9417 8.45833 18.5667 7.8 20.5 7.8C22.4333 7.8 24.0583 8.45833 25.375 9.775C26.6917 11.0917 27.35 12.7167 27.35 14.65C27.35 16.5833 26.6917 18.2083 25.375 19.525C24.0583 20.8417 22.4333 21.5 20.5 21.5ZM20.5 40C17.7667 40 15.1833 39.475 12.75 38.425C10.3167 37.375 8.19167 35.9417 6.375 34.125C4.55833 32.3083 3.125 30.1833 2.075 27.75C1.025 25.3167 0.5 22.7333 0.5 20C0.5 17.2333 1.025 14.6417 2.075 12.225C3.125 9.80833 4.55833 7.69167 6.375 5.875C8.19167 4.05833 10.3167 2.625 12.75 1.575C15.1833 0.525 17.7667 0 20.5 0C23.2667 0 25.8583 0.525 28.275 1.575C30.6917 2.625 32.8083 4.05833 34.625 5.875C36.4417 7.69167 37.875 9.80833 38.925 12.225C39.975 14.6417 40.5 17.2333 40.5 20C40.5 22.7333 39.975 25.3167 38.925 27.75C37.875 30.1833 36.4417 32.3083 34.625 34.125C32.8083 35.9417 30.6917 37.375 28.275 38.425C25.8583 39.475 23.2667 40 20.5 40ZM20.5 37C22.3333 37 24.125 36.7333 25.875 36.2C27.625 35.6667 29.35 34.7333 31.05 33.4C29.35 32.2 27.6167 31.2833 25.85 30.65C24.0833 30.0167 22.3 29.7 20.5 29.7C18.7 29.7 16.9167 30.0167 15.15 30.65C13.3833 31.2833 11.65 32.2 9.95 33.4C11.65 34.7333 13.375 35.6667 15.125 36.2C16.875 36.7333 18.6667 37 20.5 37ZM20.5 18.5C21.6333 18.5 22.5583 18.1417 23.275 17.425C23.9917 16.7083 24.35 15.7833 24.35 14.65C24.35 13.5167 23.9917 12.5917 23.275 11.875C22.5583 11.1583 21.6333 10.8 20.5 10.8C19.3667 10.8 18.4417 11.1583 17.725 11.875C17.0083 12.5917 16.65 13.5167 16.65 14.65C16.65 15.7833 17.0083 16.7083 17.725 17.425C18.4417 18.1417 19.3667 18.5 20.5 18.5Z"
+ />
\ No newline at end of file
diff --git a/src/assets/title-header.svg b/src/assets/title-header.svg
index e1a6a7f72..2e1eaee5b 100644
--- a/src/assets/title-header.svg
+++ b/src/assets/title-header.svg
@@ -5,9 +5,11 @@
>
-
\ No newline at end of file
+
+
From 37ff2e514712099f80d8a26ab50305ac03367bdd Mon Sep 17 00:00:00 2001
From: JosteinRuen <99617155+JosteinRuen@users.noreply.github.com>
Date: Fri, 4 Oct 2024 13:40:31 +0200
Subject: [PATCH 3/4] Most of core done
---
componenttree.png | Bin 0 -> 30279 bytes
src/App.jsx | 6 +--
src/Components/CommentList.jsx | 2 +-
src/Components/NewCommentForm.jsx | 8 ++--
src/Components/NewPostForm.jsx | 4 +-
src/Components/PostDetail.jsx | 51 +++++++++++++++++++++
src/Components/PostListItem.jsx | 4 +-
src/Components/Styling/PostDetail.css | 43 ++++++++++++++++++
src/Components/Styling/Posts.css | 63 ++++++++++++++++++++++++++
9 files changed, 169 insertions(+), 12 deletions(-)
create mode 100644 componenttree.png
create mode 100644 src/Components/PostDetail.jsx
create mode 100644 src/Components/Styling/PostDetail.css
create mode 100644 src/Components/Styling/Posts.css
diff --git a/componenttree.png b/componenttree.png
new file mode 100644
index 0000000000000000000000000000000000000000..b3c5a2d8873a5d450e10d1be373d52c836b9d37f
GIT binary patch
literal 30279
zcmeIbcU)81zBjxnf~cs2GoqkiB`8%95Ges22N4J;O0UvH1T+X3N`i=G1{IZF1EQeP
zlqxk?kpu`ziPWeNf&_>J0wg5lT|1sL$C*3N``owP_dd^=Kl~smYp=ET+H3uO-}2*E
zYm}+<3b_>!1WB76`S~~miARHf8OtTWD^oSEM8OY{;NzwTp_2AZU%)Toz9yC?5cD*D
zCC_6S_+9GU5r<$1lDPo?6B+VRya+)d17<&)oVe&ZIp}x0=wudR38VdkKz8Qd;_Fwl
zt*>6avM>!Zy
sg+ZMOI
z-L_@v
z)%I$zn*U~wi1F=U&D>7a??6wA;|u>?T4b@ILvD0YCzDFA5E`9H_OL-54u5+
z`>tE7MC5$mkz*SnsOdP|y}vK?UpsZ-F0+bJv+ro~)P-L#A1_Jv47^}=`os5TSP$H4
z=lHm#MJ9nzzwlZ^y;%_#i5bhiHXaZ*7-Cm5*XPe5_>(B3b1J3vWmScxjp11xV?9nm
zQM18*y41*E%)+N@l*lR#!#S`%Y_Gwqfct4o4Y0n
zw?xOOUsJ>`wQXN#ik1#CbV1nQxEaTkI`a8!V-g!
z+%P{>H&H{+W;0L*)34OS*0VprYi={VvMBxc1dWSRDjJcWR+6qEd7sc^!}+fMG6tQd
zfy4BkDJ&*}w%r2jr{9D}WL|i0M#J$-1t%}(L`I?H7iW-y8T7#U=I)%+^Mhd;{Q=c3
zHKXbN<5T#kx!!`awO{f>DAqyY46xpd6yR0O2zZBkv(YyZVfe+2_F|=mDuF*4#0YTX
zkK2&~>n3dlQE#-ekD(0NU8Z3YmZCX|OJA?Chn)gz9vF=7iQmP<&exF!!>BG|Id+Y#
zB$_N?;V_>^H=3_uAq8}Ss;pb&dHyp*0~?;rc;ReTjN!gMmt^=k2VHzAPYkFYv<)I@
zW2*+xB-Wky$ottc$%6(Fla+Qg{JDMxow6nxrAJGw6&s6l0wy7)2LkLEz@@^e?%p0WgUGxOJ
z8OG{dGbqu0>}F7;r=g|lRx8vzQ9W1O7&oJfvk6<Khw@|9`>b1&8rE%Ao&HXd7NP0JHb+C7mjU*JGn#xu&AwGje(!kB$BcErrAW{m9*pJv$W+Yu-G)Fu93%n|fgsZ~)
zonSg1S3d<2>n4oMb_oQF+;Vp
z{Kc_j8t|6eO@}wu230PV+f&`cm>tQgvrlt{_uoP?yvv3=%+dp>%sOUc2#S3Q^WByI
z-ev#098mw+WA=Z1IBVJ+1S=}l(6kq7O@fv~kPrEo4ivl-5{06BgA=8joTZ|{dY{|m
zEv9KFy5-;MqtUNFR&L<>c!81oE1o@*p6{1lWiLH;?FZ>5=03*drb?z;=RV8Mir4h=@9q%*nfUoU<8l=kFnv)@1EZ;ZTgI$az7R7I$~=BnW}sc!}#
zzSd*Eo(kDrmYscPo6g-ZahD4gnt{L%W<81RYiTpjf#)2DX(rJfR
z_>lKsUfMuu+BYgOhCgOmUVr5I#75r^#bLRB_90nzSE}LgDz2xqSZAty4(=E2HrBRf
z<-VCFxEucevrg@i;5*=)<@=4l`=<8|6a0;U@4s1fW6xN^(?1L+d5=WY-l{(gXYZRF
zt2a8|569`vhS`=6e;5vF!)2q5{ofDg>_*QHgs1%X!%_2G#q~P-hvEF)sUy$-lQR`*
zg6~o6f1|thyCt*1twUq@4|BYEcqP|6@(*+D8EHbe5%m3y551u=mNNZ^8-Hv1Fe9Js
zVVPli*>;TZ`&!=9czUqHsK{^TbjJ$5>_6AD{u|lijGk-S0SeNNxq^fLT+_`9_d+_k
zPx9OHOjKsweqYxc+$sVc6?-Z$`%Yh3S_z&nNu7XG-ERinfA~^Zfl~BQnALa8hg%uH
zWSL=Kd0yB4XYTIe&TDCs{9DOi;J$>rcPiNi4BX_T+pe=T&kHz1G#Cr3un=4UPoY?b
z&eJo)fvuE^^wW-V0X8=g#-1Gt&32;ciyz#O30C
zVK-S64d*Y#`8rzeQ@dI9XxB^*wbIwIt)fx>M%oXWnh71x9tl3DeRsLZG+V7=ri7=D
z_^Q?&`vS)a7rSCR)^PLkTQ6fN*?!uc+(1pAUz(aM4#Mr4S}y13Acg(>zyHN!<&BRt
zib%^hq?(-`=)z4ul*(0{HMIouQet?fN0)siWTS|fmekD*u7-m4*4fKT4~4@pZR6%Q
zK2hK9?yi)3-bU~`Pbn7Lp{VVxFk3hG(1F?|+vELLV^Gj$WN=^9-iW@G7W>AMFB_k}
zmTQ9RO2l+9`|^CEY~1WqexI0Q>kcBv;^FypiRdZ{8ehrSD=Oh5Bd5!DGdOc_Op<>L
zz778I>1@j=50}53mH&o=d$Lt27Y+jrzBY-`K!&72;C7c1gK&%e;fol0mfhS3&v^9o
zYgtOE168*1>lHLet&%|+6V;~HNt+3Z9F`|h8s{px!5_{Y>cZ3ha*}iyX3CdZ;Z%S%
zZbzuC2SN1ih^ZQ1y)X9@h=1JvmX7`ipXH^m`%X*?$=LvYp8$-+LvUhJ9y${c7l~rjlsgl%az{qs24eY
z;>P8=3~qVkclV22UWF+3tvg!XzE&f74H{ZvU+2k6~)ZZ5YDj6al9@J@LT$L(ll
z!+a0<=JP*KRC$TR(n2k>aWT0~ms&qj(TVb|o2)8qCR1D^Ceusp8%uF~2JMPQqz9*`
zy78nK{^c5Ey+S$t;v&clG&Hc&aU@*=r%l_7zG%Lu=ekVQ4mAx4Q|Up&;eOG9*U~&5X}G2e)angB7_Q
z*NA=vS++ydx55$&ko+&S-&9H-BDaflP?sjDJ+hgxhL~JTfB%r}6iBMjQ#JJDm#g)Q
zGB1AqmEBlP#V&H~Sz2U0dM0b38QFOC7fxgS0)JGO@F+fLm5&Q9+3NcZDWr`h`F_(%
z!r~yaq`8BR$6l5h!IhU=%Olor%nO1AkdoqYX9gNU)-E8Z3Zuhln#)ACJBNi8pukEky>u^WC4%N{;`5r#KZ{}wLi98xi_;d
zg%CO7y8|M6a#<+^gU26zPxY{UIp6QW4wSPp&}NVgvWK0Gw&M1+1xUrBBeMsmB^4vj
zNr%V`jC?R?e#glRywx@{sv;GNZp}iL7=1Cb+AUbb379M%9ZA3%so^Tx6i-6f7I}~4y+n51rt_INoMH8T0ohFry}Or7frxSM+?Hr=$>tgj71*}b`V-d7?YPM!
zAIrhA@3tYzKmku*ucx(Yk&CFhI)C0rd|b-eVmX`g=nIh)m#|{|;v3z@V@uppL2aW=
zP)UE9|HaWY56R&@<>QL3Gp5~QtM}(9An9w0^-yGQd9(%I<~fTqV0Y`&I_2Wc5UuYJ
zr>17)tSIp%m>xQLJ_W9?Lx-V%>)qaPSn|3?=q$
z+)Hy;)?Mz4yC0RPDYEG;%kFowDmgr^NXMS$O*RVi&zh6W)obq8GhCRDDf65!RyfD0
zT1H9jB0}R#0stst+7B>_xKW;37x*0hf4GU00N-J+$?w(1Yto+$-zu#8v<})iVYZOq
ze_=G;gwyAY4=%GoG*hgi#%&n-e5Gf4BexF;;U_WtTgCGT#ZoZ1Mpn7Zej0tJJrR{N
zfD4_D2OGi4;yt1g@D}`KsTsL69sYdO`Nt`>AdESt&EM5VKnR5r2}WnDdVSa$5}1M~
z^;<^z3=;gIojDu|j!yx-r|?@!@bwo*uu38w>+lP&SOEH{Y;1^hy}(*OQ$2t-Z&0^(
zy~vspE65H%W2miq={EE>u4CKr@6Jnb3(cTe82NIoL*R_trq92~ns{LaCE7fbVf}nC
zbK-pqO;)LHwp?Ybmy8YNd}ubZ6)e=|idf$w>Gpahu!wezWeS~iI$^ZZulmp=FtRQ
zbW29L!K9y6VL>cyL)0O$oC#LTgDtm=xMOmgX!HVa7fq>@aBxZqS7Tea3~}YrrF*vr
zb^KslMKS75ix+;a59`$3{&k}x40ObctVm{`8$RsE)B!u!bKCG_3VoT^BoiM=9hs>y
z#FGWVBDM7$BStf_*IGO`WH?apG@C!)nSC`99ew%BjP-2WQF!N%diqyb*9M%^x9VS)
znHq`E*#{A)!_;3tA*t7O`7fizSN5{;S`w__H|{;`D?J8n$)n0D
z@gltsPLsykvcI>RIZ7E|1)6}btk*lGnDZNrw5#9Yh)=a<
zVO}*>R{|WT2U90rrA^#-b32$d(PZ_ut}3%EDHG#Gs-3!rnC_r96iw
zZ%OMHIbrp~n?uf5%Shp}c_RplzgXFUa7LJC&Ywb6zg#7G8OU2DZ2c8IGBOCUc*EBq
zFLJINUyKWBb>p(MYd%H{9UjpmV^D*Z`+ARNFOqM?)SJ5xDd;d)FT}{!=SUcHhB5>1
zW=V2}oGnC`^T?$gs6acZ+-$pzKvCCD`+wNaRaE6z?k
z3W7&87BMOK8_ZUbjm;bD5(c4-g&Qdw=>=J#jsUf_IkPY$iTf(ac8Nh}-Oh|bzdJ13
z{WNp&t-gdeT|~YFp5H%3`e0@4by%Qfv2P)l7EJq9T&I7lJ!1YWc=)Dn&oa06Ny5VC
zI7UdM&ftYk)&q^GM}dp&hZU`iI3u-Nc&)xhHlZIpuF3Uy{g8IpH6|~ZY*?KMfN%EX
z>6r$pXf#!?dxyvIMqQ>vYTQXIU7z|Wj_926ahDb5Xv0zy9AO>GU0?Za_10pcS#WyS
zUqwm*&OzkQuGqa7bHFg&gwGjgv?
zf9jd1-uT13@%F5V^$P$TcVOy^SRc$o7<`gq`_d!U{m7@eEqOP%dzZ-XtugjyP}ch8
z{&U^!$Z4@}W#jfLXw-jwQEQIy)Tx_6XWf}t-l~pQs~#xJ3~tw>y*Jk=W-2E>%@+7d
zy1j{r`P90sMonfpVpBUR7e1@lzPD&uF}CJG{J>RzPMg%ay!Zs3RZ-Lm`=xvMto;rZ
zw60rb=3f)YzVp@xb0L
zFIlTbWSs<>Yx*K9E41&?Qa4h>Iwr&OmR`QZ&oygj>xS4R;WzOxTcZsTWA;$Q(juAq
zR8Bir{bx>^=$7>kLE3y55$jOC7X^iqA}t`taxRZQ%B~5uQ(rB(tjNo8)jTj97N=JA
zkisVNT|lTGLU&jHoZX~MnI=|V-rG~|si}V*{rF*LlaBLWuZkU?j-u$#K=9N9Hfos;
zuk*=Ud{~r4-eF`xzyn%wR{1ajPnsV+VA8uR@gqY2D&VB5!jT+*+>|hMqT;heYOK#r
zX;3rH?V_w}iNelgP>bd>mU)D3bVj%Aq=B3!h?Pa?>G{Wwe|)Ct=g~_m)t}|un!eHP
zyy}4GMOMv?#YpvnD6pkihP3AI+(e|%sgW*kaG^3jMsKg=IIRi0*5gEw7yGwI5dMK1
z{blC=zdSthpB-G9tqp(?J)b`ME38SYI6qw{{>>?yKW*_sYzv@q08_mAI{!~+xNttn
z73pXC4CLZ0{|es1`)PLrfN_0)MY>;vy24^UOUz
zzmDDfjXDDr)A!he?ybKENZ?ukOsqJHyDF_4P=ERlEov1jr6)@izsGyLw3OFyq)NYO
z{T-pRDEu}5fl1-4FXS#~DlQgmtpfvvLijP~Bv%X4ytzH*lBK?K=bJ&uT^my@0_C6o
zS@VgXq<7yld8kOKR2ypAcWb$X&SZ{-e3)2t_eiA#l=|j}=S}&W6a9t*p(p9}JrLBn
zf7^x+6_@u03`j$^2^2Zu)gWl|4?r*l-h-gA>wrxH-xGn1O@UqtZWDqIYy-R!xE|0_
z{Q$I7pf7-Cy0ttSiuT*|1JGIh40Ki&!`C4wXFK4U-~s&iZgO4c3;aF^g1ecub_rIl
zoB%_U0z(6O6hNnEtp(HZ@A+cWmROnc>bc;F8VRUp^dTS)^`5`dG$6xzoSz^_3z53v
zDjjn%+aGfLl(Yg$t*Ml4Sx+k0n#A;64T7FruRkaPY3T;sDe^Pah3xmaWmWI~fv_nAdqxovLwTmedP~2OUA0f@)&h;&Qnm2o=BgHyo
zN{@q&J1DPd4mQZF#QT%=pt$xz_(SW7vquOLIXhh+fac4s^G&(hklOU_Wl(G8mA!`V
zOGQrqYPSott(y4d4p!ROy#6TYm2a*^{4D7A=aZn{dMmxd@4Nl$8lBtua?!~blSCn(
z_Je5(Uno$;tG_Sx|LFv-da*5SsA#Z&9RRJ*0=EmY7XeS8@HVbI-S^_Sf8HL2@ioGm
z*Cd)=^`xus^ccZV8{&G{N=7f+7qB(I@?8fm;tVwVvS>8~zH-pQKQC7>*9DDTbJz^6
z@2I$v+VjgH!Q>;6jy2^6Ak{4^pXxm9ywI5~TihmLjBFi;odQfOVqE*~2SQO=
zg&jWo!K}AF!lj{1R$KX4~MF-ySTI9^aQme_%N-(V_cYOW7$pkK~Q1|GPJ&&rDM07uuQ-7!^g2sVEta1&H@e+3$zsv+imnr~@Uizl8h52*d#bZxg&P}=qXcHowOJX@Bx00F%i7?9RJ=3PE0aR1oz1YP`
z|3!esx&aEJQQK_~Ql;32`KQjz0j<-$`p-X=Dg(?F=LlznNw8k+>K*{dnsDL>3vsLl
zW>l$!ZsFEX?*W?VYYQnPts17hM(+>U^Xy@?SG9$)=iX|M`f;~@~6T`
zNPZ_WDJY8JM7t^<_;9japXq%5ZAH4RW5Lk(%ggc0K>#*4e6bAL4W~_{+-nMsQ-HDn
zixkM#oLmK53Z-MzkcqLXVfQ$ZCabBgMw}L_!22UbU%M+Rq`WG4j$CNxA
zk8B(O$vDU|$VBqn_Iu>WQ7zhQ4ea?Ekk0!X2lqJmCN<3U6)xQXTCxU!cOWtQp4E)q
zizC87AGc&vZ`fgN+Qf((O~43bVb(Ho)8p(iNtfe3W$Y3
z!WNDc5)ZIG4Vi)itb-M$8Bd*gskn5G&*5-k#%L;$IKK%N6DB(a?h1$
zPdx}3|NddhNm73W;J#1S6kUe|OYx5<(*(5HPOH*_
zpoY21(qjFquJg5&B$(34K9$ro;;j+kAZ;qM8YtwDrTSQzSsozCxM3n4$4ob$bmhKJ
zNd~xEQD$hLpEt}ZJSXic$UHv8O0G`a9Qq;GIsD558X%=g^%I8xrkw=yIBYu2cXPzV
zQyPq6=mGYN1h_00D?iesvl(a0%nW~0MQW)L4lNnN2r?`M1LRvN5C<}ft4rq7zS2iC
zg46{p4Z-p3nM`^joEaMBSHR>S?N_VFQw@`Oiu}`j42-HWhIxQ`afN{wxwQe;lX@P7
zeZRBV)~$t+li=42Wrb?l(L*ZUN^Zd^SJhU$5}c)mjemJC0g%kWUC?Z>-{S9S{w#QvhBYe$+OU2!;(4W!n2&
z+Ee-SRD#6MFo8HI0y0b8?#|aNLl`%gK7m%$(^m0#2PfVj|Bf8o0flor@vclnU1(XJ
za{SgyR-)MxZ_+YRNiGKynv;!3fl}~n!;n?X!wKc1nw2M@M1YOZ5kDU#MbT!TI7c6d
z4@P@1Vy!U~oXs*2O(1n$sh|OfHHUBMmtZrg+x3&nW)NGCAIuTAfCZZj@5#&UnNpi%^bN80uhd=5I-zEv#vnwUkTt
z3Tp+-)h^GPtEff+*eb$ji$~YB?{H3cPC%G+kldD7EU=pHT~+hzeVs74Ur$=a1cfpo
z>Hii5ZvR8-I;rS<7qKxwjuv~MP(Ngd8*^}?_nj{*6C#%IkU6wZ_0LnT2<_a^(w^3A
zICY+e1bwv^%Mst)o0d@ho7LD|o7XTq+vBbzas<{+hNM`RY`xH?O)&`1$|*3M^kerK
zNu22$bgYaF?Nod3
z4~fkLF!Rk>RPBNwZ#$bl6*mqsyf~Lu79qIeLHl*0rv;Vid_?b)
z`N1S-XT7cFCCd_%8N40h>Eb(kO%l%0n#9%=&8N8>>NQIY>pc48u8R?1fHcND6&LLr
zw#;y4@<(Q1fQi3RDpZEI<8(`4jzNCQq|~)C8|B>NF}a!RtLWJgJxxkXTOd%b>-Jw;
ztX7xA+FzcqYd#_DD^XCcr5vw8@HBE={PC%{5#X||8m=B22<;DGhqd0y<4qV`jYYaG
zypYXbLNT2DvckU)Do#IG`80N0??$bfvFV>fUwK`#c#-n!#JQGT?ox-#f=|mV{ruwg
zK=L9nDu1W=(T97bY-GxIXqshY&Q(?oRLzm!68r@>2J94Uj8aN7224c@BLf^!yGXCo
z*L98TDGrkHu?&TF77;yf@-pHntI@2P8Fmf%?L6I|r8P5yAXEF|>0u6k>e9D3XYh=n
zhSVpS_MJ_c6|rIRGVN-nG4FVpW*0X|DI(dAtdgo5CIhs2n=W@hmWSe6{uLm>U(~y)
zSug?9knA5{WhSStyhEQ{wA<~`z6SgCa!6>)&asx)t>uh>ZTju3k}y~t%UE6Uz>DsH
z!VlcGk&qoc(=8qS+6#{Fytej8gro;nW~bEGIjb9G$0gJIY-+Ba9O^?dk5<2L+9|sk
zH>!nqD0%kzH|^>~^xLi1y5cS&TGQUD=Vh))busm4u5xrccn`RY9`gV_=@M*SXImHu
zsVaRJz!kFV!M;*&?liKm7-*tP0UxrOEq9Ewzb=dw7zC?=qwH!2vcD=7oCD{N+hf^{
zWV-sZk1cq~>@
zY2<^(mqUvDcZx|sQ&E8pXe>Edcv2Typ8$udx3AdCclp(Jhr0p<75#k5aPC81<00oz
zaoXlF*6MQ@Cqb-!jp0`7M&?90xx~bB=;Rat6H$7fuWu)wv~xN6G8@D#goo9>veqTL
zD!`*;?3)o#wF{O^Z~*D;Ons-$+z`f_ZcfRIH>z#aazU9zyjYiQEj+Tqaxy}nvTTcN
z2O)b4;oiIcRDgBC7h47S*t^(&XoDn0i^9RW0Q{;T@PqmDt^$2lP+#1g;!$UPFcIVAaN(p
z?=SB*5RPXV=<#=Zz>)-;Qb7WAy1Y$C1y;>7`WKsFHBIRc7r0*vQec6>)n5R<8^T{A
zW9Q1*RY~H;x`P*N_ycsLfWy@)XDHW2v-SfRqvFLMmnrDcR`byQ`<6qZMjoipg^?2_
zEq-<|(k&e=BXhV>ryyu^_*gEx51HbOHq)DawT_gKJ$v6<()i9I$!ty?igs
zSZ6N|&{sr5_80#+a}EMIV}H`&Y;bgb47bd&LFqln1ReGU)`8Mb7DMCwE*q=jPu8K!
zXjOC&>}lU``Qj0eY4s$+CwNICcU(?kCq!(|jy(kH{H1?G@1bX+lc6y5LfP<-#BZW=^!W)I|%06U9MM
z{+uRBBkNL1Le@bkUvQe?&D|3gFTzHG!+0coY{%&$Dq6^ID=*ItMKHrfzC`jbNh;V=
zX)4tSW#a3C@)<;sDW1$MCmU%mCqDA6S+W+rUtLdAqrnn?{>Ea*;#!d>so!Nu#XU23
zZzC?X9cLD4b0Sfa=C`$KHq4F$gUNAgFbqIv<)k_vQWhww5(DqGL>2MbHHK~pi(ocD
z;9ZSXcdMI2;duiC+0A=79JT+@`uEZH-^m=D@qQmo{#zxy=~Zhx`%W*HaeVO4?Ee3q
zSD+`4^Os3EW=Kb4Q@ceV`;(n9;{U`HprXfqCNVueVmXRnOMq;MIWa9Bn3Y9E42K-(|<30m5e?-dJ^v0CAeq*>Hl8$o0W7wmU;z(
z+#%UQ=Gxqd1EO`rDyIN1GFzS?K)fCtj{&c7%_(2Wlj
zhwJl;D@5W*%a=jXKV(#0r&J{AxS!vc3ugON=lbdNs`nDA>f3*WpkG?IWhcE4%TW`4
zG4-&4$^)jc(+z6~+OQ|?qU}-YrK%0WZ>^s$N^BGh*dx50>Su>tQIdV9Vnv~*>khBV
zk8@X7ycS-o{JQUh+0CcpegHP{?LI${kABhbSpRQ+p+g#w^(?s&ugJOVI-_6*c|1QPgjXc+zA
z4xjDqh?4xU|J&{Eh+Bv?gb@`IoUfJv#c2{8-`0<6m+ne&3GIc2v+{w@a)An(sw}j<
z4IDqy0gD=wU|6qB?Ew!cfQ5EbIN&{FT#*=i9B7wLRTVTlX!
zk6M4_=iNKJh|I6Bxeo@P9xKMb`{OKt(Dv&NnVboLcz6TwqSV6@RT(Z=q`C#Ed02*aqC^1Ne
z(N(suPzV~cQe7F=X_2V>L28nKhZh86h&I{BjlN!5lL%l{#yd#44m$_XLl$+ZAEyFL
zr96Dum;8)mSb#Yt4*Z3UCvh-9GQnNU#4T~yb3oi(TK`EpNSPTKr00z)AsjxID`H#9E7bEj!#=V#dpy%#dH2+XO)2>h1@l?>M#h)
zn1?;K8dl-&6NmtoI#Ftu_|;Da+PR-Nuap_iaH2Y@*N)vo3;6St#Sc;QgN!I=EQiLX
zkNj9MagONcX?5|%y75PWQ~*PgV5xezpftR@aC|=N+zTlosLCHoF4?p10#!ukmT(Wz
zncap38Zin97^dII{WeiXQirX+MJ6qA09s}N*?kEtoM-PV7T*CcW{}ea6Cb3wI%W%a
z^pwqE15cNb&&@>>N~0$IY3Ji3oEri@&o48U3YV!j05blEk7AuaSjcnj-Idt1i(nU10xQ%b0gm?=sYPyq
z^H3Z!*0Oj*EfbP&7Vd@e;XfdyqJ<$n7l6cBC&NT`zBRMH+gTtpW}#k^+4--7yL@=DiXKS<1=6|Q*XB85F_MQTL6#+>t(4FT%ye%
zU3|U51&2MVhmiGG(BJjG3>ax=`7SkC)e!h**Wn(3V^m`zSrJz
z+0Gq$vgYlta}afBSv8p}lH-gK7A=0xdLgQ6pR5~=1U~a^01aS|MctUPlz)2s-X14IXb&pRWFTID!iLk9efEj$(`b^pI!)1r&H@gr2efs_#Py8KuhM0tttsS3dCm+e?V7?bxOT6dFx?L29x-
z?Gbo8*#r`=cxwR!El*a7Zuz^(zvuGrMf9J3dfZ3ym&v8;c!~LtkBC9hcQUHBP%5^{
zYexJc2Xfefie)wV(!J5WTA*4I_^8@j?SQuut=V@#;k50#0VXAWhjf7HABfC0=&eLw
zy-#=^xxo*lx9IgFtITkhIhw++slMHKcS&N#RREro!+GlbC0)n
z^Z~m28SB#;+_QlYii>|BXI|!37MA;kmK`zW5KP+NdXFGNzzc6#b>B)BTqp^!?25|5
zQb8YMR-RdYcMyrdN1|a@Ti;pe0`P1kr8G=<(?AXe_^C%*DLVaUZNy3|4M9L1BH6|4
zo4x>w*d*Hl!HV{BxrFYipr)&PgiFUZ!emKk)%|)!LlqA=2qNq?9qkbys=evvFXDZX
zi@mhN8sW!;ls=YS=+;e!Ibmg?IT$9FS($W$g0moJ520IvAQuZyXNrxLVWotbRPt)z
zi$jB`I|UZE!?lgP!3PVUcfzU`^=Lr=Ypu}Z3Uk*q-V9j-q_aUB*nBD1?ls@mKQvcW
z23|^mOE6W5n~`x#GyV@}VKtD!d=0tyQ@hZky}=dsKH=H0geeo)R=nd4=ak{KL!za)
zxf(4^$5WVag&${-Kj4#uMq$7z(iW)#taMh@hf{HKqh5BM)6I%**-NtpLPE|N6lDrY
zAs_$db>-@hc0Ca~2^@Mwl9HR#`jK!!ERgXQ8I8&VcP-V$^r2nhAT?UrQ@FN^=VEv;
zGbe4(4oGMKRv@MHWNyK^DEq>bw^tIwz-*$ML?pX5Ye_{{4TUpm6O`*Bff7Zd%Y77f
zo+#pgo=RN<(_$`U6UA~e&xC@)UOkKLY>X@Wv0XPqn$~v!Mu8fbuz8BzSYGD~*J3IK
z?#J=N>Fb7gZB(A6v=2xC=~!@^iad@rVqq*p{|1`cdopqJ5vglRIy<1FW3#UiMo*`H
z=7OilKJ38G<>s0~LnG{E_HXpxWLrlNk$)rH0-Yw8VPfu1G{IKt%F$#2;`vb&lXxWo
zQDCrhE#{^CkhKs+fDsODs1F#8Nz%Fl)<7g>eK*Sx&b6hlD*=NA>*uK%u*yQD1IjX#
zDT>4^57#XRK7>d1dRJ8IZkD}7sEJs{+!Hs}JFHTWxAQb{z7clGeL7Y`FMkgy6M|nn
z;kCm;Eykm>QU&71g`Izxc0e>@42ySvG84Vsa^?2SYImuNtab+}N0^lkk3ivw+9Bvq
zW3lSxE27Kt=)l5Ubjh+&S7u^l&nT5D3jr@B@^NnaM&Hb11YIycL}0;7Wqm-qskja
z2{0AAE3OTwKcIheI+X3K9L};Guh9%HDNk6dghX6AKJ;7#sV^W0)ChR3u$*E57ijes
zFoDgOO&sn7w*~dUpb8}3YiXxCVDdI9vbTF5hyNaZ{tGbM8jKG3#@u(laR5(d-$Czo
zoI>J(+GBFkdnb4B=Qf@F9X$a}3?-9ch&15(`V)aT%T`5-|y
z+;bTu$QD~6(eP6eV!*L*5E7q#wF*SynpdFZW4~@(1vd!t3-9+?W`tcn{2=Vx+ZyoOy7ni+5yH2>{)e|S
zyoae45rGvr|0i!}0ausqHT_!kiAP1pXzrU?t=9R!!Y}vzf>Cl62mdjYrrWK06{vXOxIF*2{bj7F
z;>xc&w(Y1{q^Y(AShhTkm)U2yMvUJu$T3~)qta)V~Al0={bAKkH=y3)2a
zHr%cg6q(w=W_&Gn~`D$^^;4%f%c`4=RA-$I>Y`0Gzizb=U~2qV}WGp58(uSHnlPf
zu7V3FJJ*`=$AvuuWgajCY|%j2s#e|pM271i=(?DBVk49zM$$_q0G@}K(m4B|j8RgT
zoE0`y16N3*39Sr(Rs2Ss7WM_hSuc=Q*6`-43B`(T7+R7yY$At?3Gpv}2D&&kr?XEF
z!#o72Fu|l5!8{NP*fu`DqwkoX>7z7OIfwRov#Ve^I9%&Ud5ytWV?J+fvW>6(u752K
zP=hAb${tixio913c%f2#4;k(NDCkN9EHqkLYqX}$+p}S0r^c@4O~I{sb!jpm>pw2j
zP={VejZMbvcp3F
z|J@xAJ9JXO>`%RO(V@8EqI$tyWUS7btm-ehdVG_
z16O;$P3v%iLoH~%l2ID*{E|B+k@0rKnS;us|u}d=bkU4Z6sg(
zMcObQSYoipFW-g>5NS`q#2slRP+GIvg0SUN;d;QrLK0TL`Zzk0U{xZ3v+~kQN2g|h
zB3xCdXiY~qWD21on7@<`0?ja!;Jf*)%rvYhkh|rDcrOX=f!ysKtr#Iv1e=pURVIRj
zDMnT5oD6CbOa=|i>6yXj7uxmcU5tg1h#+8Ek{jPqWVUdZ*~Y$^yaFgtK>?}6r;%-7
zvK@?oQzixW+(b^txfOkS2kTiC!(tvAtO4RjDkunbQ+LQ7XPcb?uQu&1L}opxEtUjx
z;Oq!A-YKB6J1-uQ>o_$7@D2;U1BQoDhp`&&fOqpT?7Z1W?Y6&|I0WwlsFtzhqAb&k
zxx0CH@AO?4&GRtZXT7}+jea^NZVXGErT5D$-}&q!KrLLt#=Q!J4jHT0#F89wW4JSn
zsZ8fEWkmu&&K}jpqWgMF0jk8B3L^;XZ3`=KUFyis2y}dzJMn}A8(KgSh=L?IcV_!G
z0IyO>f%8t~--H5%s?7GEq^e|UElOI-K_!ToJlL;6b76+t@fQGgS6Y|L`cPJm&`(vm
z)Y>OvjinegIv?6aFwd@wJ&@3hr|&Z9fc3bw{byJPO5#MpI^{{AK4mWgtPbBpABA@@
z@=4L+2WL-bd3cWb@@S0Ss3Mjr*RozfLWaWqo1Je?_Mas79
zGNJ%Y``iYr{D}aM8{x90tc-Y{)}#mxHo7PUCj~nNVHt0nE$VOtERhgPwFgR&=7q}A
zsN$=8q^gA0m}tKm5o-lE)O0v3(Xg6KH&}9Z){jSiauEGiucq2&3Q6$A2BJ2T0`!X2
zWz(|79Xo~NJ9`#semi|LT5o5t%xY6nO6Gy|tm}oChNm}5;mU&A&h5O!!3&@~;l-#;
z1V$q9a8h$-hry?>%)TFt#-Ond~J&$`m=`yelaG5OO}XIYGyvsTfE*o{k>SPw?l!RpCntZmJ=m-*`7-
zHGBDq)SWAP224Zu(&n?)L$nBVt-V60mt+U5E8;E$6B3$@FudOB?a;lSF-b#V2<
zdiq;r2oECpa7}z?2HFKbkqnn?A+EtKyyV((GJgx1>-D9a+rIS|loN5XcXNXE4p33e
zZQ6GuwDU+y6pgX&-pErgNmNNo!s}t?%4oRSO|3g|e$*G}uy;8CQ8P9LF1)ss3HyBF
zC5(NuF+L4SRth+*Ef$Ntrn6OIA#%Z
z%Q;@D+V@VvvZL#r9W=c~lKoj;mwx1|j9BlJ(D{V5+D-4~Zrl~}Hs!bn&O7wt(knon
zu6u~Ma`B@MN4)8l*wFQ%QkH1LY;g@vFD8@Idq;EUeA3q);Ng#J${hUxu6E=yu=4~c
zp%Pc6YP@a*EzIoWT^p)QIL*;OuVGu<6V(zHhu3PbhJyjn+lR8nT?Maca)+hvmF>?I
zM`2d8>gfJxf$JS$v?!K;vw2A{?cF4Sjws_7%{xXgB1+qT5>Xo3vJ6jYf-%FeT(S98*v*I
zr7oaF=A5q^ZM7Dij1=rk%R`6zs-MM|wj8De50;8+ZH(Yx;6G~M+8pp=dV*(uI!SL^
zu#JN05KY4^LsOTU;h*3gNQyH2BxUuGV1q)o4J7y%S&B~c>N-*S-8CvEHYL+Zi*1o;
zfb}K8bsn|H%${Upln6GWqpg-{hrn_ey=kE6f9+_Y$L~)A3B*7f5^}abC+%2BJF?-9
z4FMg|=rei6v{7SaS&QFKpvuk-C0rYskPyFagEykRZ$3*vuZmPhQ~hz7%naUy>MV<$
zK(?InXH9eCy;=IS#bBhLzu;C4VW4@0p%lL-KCF*SqR^@a+^}!B1ph!%bHZZVyk!LM
z4%t#cFfz=;O;V%y^i%1yo{hGrJQsVxe!hgijVQ=cI*|on*9ZHm>D*IN7iC(NEC#(2
zEXV79P`Yh-@otXx^Pm@l;>uDP>$dqKPKnZ;7ZCv8WEW|8?yrmQF)G%6ehwQbn&N!U
z5TLwklrEUrXXNb1TfI%(lQwteskXRj3N(HL>6-sHaL$KK!$
z7DNWU_!4U(^#q+&&MT1u=&a@^Yb+{MpEfLRjv0_jWIa>5G;^l^gIuQ)9DhV#=A5_o
zz53)S|19`32_}9oZkUbjg}td>2+J24nWD)q7o{#LF=tac%g`%)UnFF{(W`mW^Qa)(
zarJ?*9J$sVZ!I4t4w~qN1V>4oSohTn;f|`jAzp!*ZxTPM7vhh0Jae!=_CO7l0%VaP
zDJZXbGE4;#bVRI6w3D-VRMj%$)|l_op${LhRiV(2y_E@?+Y9#dVXr9gxm+}uNh22(xYE**Qm5Yo
z@m20IV4xe^tG8LZ;LuLZmM=DXle;OzqstQp(Rzlv3qZxb7WIb8ogFRu)1Yo@=I(U-
z9Tz<*ENg?$PmuRDn}Yyxt;7*{nG-)cBOzjNa+r3j-vg-rk)BzCuVjUIje$=PglI
zBnsjK5NMr#1YX--P(|xA!=QZr^{lKOZ8pi;_yRop6ICr!DfNejenvGAfx~d09_6K(
za-ubYnVrPo+^5Yxj5PrzsVEXhKkltr9xR#+^G&Yy2lTHfl{qOhMRjWM;yN{RR;ZUp
z-zIcEV%@q_V_0_v?Ll*9BJ=~$hIr?Cy?71EklDqAMRL?HqK_twkDg9oEcZ6GQm`8d
zKUj117|J{@c0Y#xvgHbM-ELYfGNE}Nrw>5t)+kF-oyITO<>Ib264oVBi7qyJ-l_!L
z&>dAm^O?T?xLQ>|p!KrNs>BMZQ3L9*2B7rX58S7#
ziq()RBFClxA@Xh{W?U*lre|c1m!Y|f#fjaQut;j=G-ftx*9amro3rp)&Bms(9
zoIF_6!l(JOI0nfrWYjq=4j;Yy!$=r8iiSnZCowITCzj%QC7j4cjcWREcg0ife9Ql~
znY#zroebv(Y>Yrjf)v;@KLJvt$_9{*Y3L4J98NEFANoC9`UgA#Vy`-oL=k~n+76ad
zqKUf-x$;C2R>!P?vG_oLJ-?YsCD_t+4t$EUr-lk0Ut^9Y?10muV?)?STJ!4&fR#
z==Y=aU)uvUWW@)#!X4~6Em{W!fQ*j@r(@F5p+Kl0H)at!vpm|z^RK@76GWRW&6G*5
zjwN5gTOs+g;o%fGhYeqm3Z35Y7i)!I0*wKx8feAUM=~{qbzK{bI!3m2h~{|w9-93F
z^#a@cT*sj`u=xGnK;%ptP$=Na7>J-5Eci1-UH)QO@Sjlv)ydsvdXH2444FUbU`$JS
z87mFpzjG6E&Dy9Dh)vIsfZJTn4F@YC+(0o3cEkez&$IkpMzudxQ8L75`FBXrw|R>B
zSL*(cqcaE3wz}CY%r*Y;@ciA(Kf{W@=O#z&zkJ<%4=v|!ZuK8N{iH9StyL`eMIg*1
zJ6DfZ{yzh>A^8_7fQI_}Pfr53-QSb&zy2f?CkhnLU(%knxI1YH?kHq-81-|>LHC&d
E15U?{l>h($
literal 0
HcmV?d00001
diff --git a/src/App.jsx b/src/App.jsx
index fa9aebefd..1ee562d96 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -37,7 +37,7 @@ function App() {
const postsWithComments = data.map(post => ({ ...post, comments: post.comments || [] }));
setPosts(postsWithComments);
} catch (error) {
- console.error('Error fetching posts:', error);
+ console.error('Error fetching posts:', error)
}
};
@@ -49,10 +49,10 @@ function App() {
const fetchFriendList = async () => {
try {
const response = await fetch('https://boolean-uk-api-server.fly.dev/josteinruen/contact');
- const data = await response.json();
+ const data = await response.json()
setFriendList(data);
} catch (error) {
- console.error('Error fetching friend list:', error);
+ console.error('Error fetching friend list:', error)
}
};
diff --git a/src/Components/CommentList.jsx b/src/Components/CommentList.jsx
index 155e14ed8..c68862527 100644
--- a/src/Components/CommentList.jsx
+++ b/src/Components/CommentList.jsx
@@ -49,7 +49,7 @@ function CommentList({ postId }) {
)}
- );
+ )
}
export default CommentList;
\ No newline at end of file
diff --git a/src/Components/NewCommentForm.jsx b/src/Components/NewCommentForm.jsx
index fd3faab65..b0c2cce24 100644
--- a/src/Components/NewCommentForm.jsx
+++ b/src/Components/NewCommentForm.jsx
@@ -35,12 +35,12 @@ function NewCommentForm({ postId }) {
: post
)
);
- setContent("");
+ setContent("")
} else {
- console.error('Error creating comment:', response.statusText);
+ console.error('Error creating comment:', response.statusText)
}
} catch (error) {
- console.error('Error creating comment:', error);
+ console.error('Error creating comment:', error)
}
};
@@ -55,7 +55,7 @@ function NewCommentForm({ postId }) {
Loading...
;
+ }
+
+ const postAuthor = friendList.find(friend => friend.id === post.contactId);
+ const initials = postAuthor ? `${postAuthor.firstName[0]}${postAuthor.lastName[0]}`.toUpperCase() : "NA";
+ const authorName = postAuthor ? `${postAuthor.firstName} ${postAuthor.lastName}` : "Unknown";
+
+ return (
+