Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
871efad
feat/added feature for email and password validaion
moueedAli Sep 3, 2025
1619055
fix/removed_email_and_password
moueedAli Sep 3, 2025
d45d345
feat/added new feature to perform checks against DB for existing email
moueedAli Sep 3, 2025
676d083
updated step one and two
lindadqd Sep 3, 2025
6687919
Added password feature and fixed prettier
Sep 3, 2025
4bc89b8
Fixed mobile number input
lindadqd Sep 3, 2025
fb52174
updated placeholder in mobile number
lindadqd Sep 3, 2025
4746a82
Merge pull request #6 from boolean-uk/2-client--validate-inputs-creat…
magnusgit1 Sep 3, 2025
6859c6a
updated bio-stepFour
lindadqd Sep 3, 2025
da9c05d
feat/added step three in create profile
mariehhansen Sep 4, 2025
3f6fe18
Updated next buttons - user has to fill in correct input
lindadqd Sep 4, 2025
f08502b
feat/added feature for email and password check against database for …
moueedAli Sep 4, 2025
6793813
Merge branch 'main' into passwordfeature
magnusgit1 Sep 5, 2025
223bc30
Merge pull request #8 from lindadqd/passwordfeature
magnusgit1 Sep 5, 2025
4981692
Merge pull request #11 from boolean-uk/7-client-validate-inputs-creat…
magnusgit1 Sep 5, 2025
3a310a0
Fixed createProfile to match ticket
lindadqd Sep 5, 2025
5185703
Fixed autofill email and password
lindadqd Sep 9, 2025
5b9bdcc
Merge remote-tracking branch 'origin/1-client---profile-creation' int…
lindadqd Sep 9, 2025
2a8d2c7
fixed missing steps from merge
lindadqd Sep 9, 2025
98b4a9f
Upload profile picture ok
lindadqd Sep 10, 2025
17837c5
missing form context
lindadqd Sep 10, 2025
0ddf2e0
refactor
lindadqd Sep 10, 2025
5d1c57d
Merge branch 'main' into 21-client-profile-creation-add-picture
magnusgit1 Sep 10, 2025
1c8613b
add file structure and route for Student View Cohort page
mariehhansen Sep 10, 2025
d2126ed
Merge branch 'main' into profile-creation-linda
magnusgit1 Sep 11, 2025
e2061d6
Merge pull request #10 from boolean-uk/profile-creation-linda
magnusgit1 Sep 11, 2025
6d29f5f
Merge pull request #23 from boolean-uk/15-client---cohorts-page---stu…
magnusgit1 Sep 11, 2025
3d9ccfe
Merge branch 'main' into 21-client-profile-creation-add-picture
magnusgit1 Sep 11, 2025
3d3a0dd
Merge pull request #22 from boolean-uk/21-client-profile-creation-add…
magnusgit1 Sep 11, 2025
9bebb8a
fixed issues from merge
lindadqd Sep 11, 2025
c665e94
Merge pull request #28 from boolean-uk/fix/fix-issues-with-previous-m…
magnusgit1 Sep 11, 2025
390e24a
fixed log in issue
lindadqd Sep 11, 2025
e355c64
Merge pull request #29 from boolean-uk/fix/fix-issues-with-previous-m…
magnusgit1 Sep 11, 2025
ecbed05
feat/added feature for my exercises part in Cohorts page - Student view
moueedAli Sep 11, 2025
ee6799a
Added component for view all teachers
Sep 11, 2025
afbbbaa
fix/fixed issue from Daves last comment
moueedAli Sep 11, 2025
e63eba5
Merge pull request #30 from boolean-uk/feat/add-box-for-my-exercises
magnusgit1 Sep 11, 2025
3e710c1
Added function to three dots
Sep 11, 2025
61fa1de
fixed issues with submit profile
lindadqd Sep 12, 2025
3e51528
Merge pull request #47 from boolean-uk/fix/fix-renaming-issues-to-mat…
magnusgit1 Sep 12, 2025
73daa4b
Merge branch 'main' into 18-client---cohorts-page---student-view---te…
Isabelltran Sep 12, 2025
63f48bf
Merge pull request #43 from boolean-uk/18-client---cohorts-page---stu…
magnusgit1 Sep 12, 2025
09511d2
fixed so that we see posts
Sep 12, 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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*

.vscode
.vscode
.idea

3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

src/*
src/
32 changes: 28 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-modal": "^3.16.1",
"react-password-checklist": "^1.8.1",
"react-router-dom": "^6.8.0",
"react-scripts": "5.0.1",
"reactjs-popup": "^2.0.6",
"web-vitals": "^3.1.1"
},
"scripts": {
Expand Down Expand Up @@ -43,7 +45,7 @@
},
"devDependencies": {
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-config-prettier": "^9.1.2",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-n": "^16.6.2",
Expand Down
5 changes: 5 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@
.ReactModal__Html--open {
overflow: hidden;
}

.border-line {
border-bottom: 1px solid var(--color-blue5);
padding: 20px 10px;
}
14 changes: 13 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,21 @@ import Verification from './pages/verification';
import { AuthProvider, ProtectedRoute } from './context/auth';
import { ModalProvider } from './context/modal';
import Welcome from './pages/welcome';
import { FormProvider } from './context/form';
import Cohort from './pages/cohort';


const App = () => {
return (
<>
<AuthProvider>
<FormProvider>
<ModalProvider>
<Routes>
<Route path="login" element={<Login />} />
<Route path="register" element={<Register />} />
<Route path="loading" element={<Loading />} />
<Route path="verification" element={<Verification />} />

<Route
index
element={
Expand All @@ -36,8 +39,17 @@ const App = () => {
</ProtectedRoute>
}
/>
<Route
path="cohorts"
element={
<ProtectedRoute>
<Cohort />
</ProtectedRoute>
}
/>
</Routes>
</ModalProvider>
</FormProvider>
</AuthProvider>
</>
);
Expand Down
75 changes: 75 additions & 0 deletions src/components/dropdown/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React, { useState, useRef, useEffect } from "react";

function DropdownMenu({
label,
options = [],
value,
onChange,
placeholder = "Select an option",
}) {
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef(null);

const toggleDropdown = () => setIsOpen((prev) => !prev);

const handleOptionClick = (optionValue) => {
onChange(optionValue);
setIsOpen(false);
};

const handleClickOutside = (event) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
setIsOpen(false);
}
};

useEffect(() => {
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);

const normalizedOptions = Array.isArray(options)
? options.map((opt) =>
typeof opt === "object"
? { label: opt.label, value: opt.value }
: { label: opt, value: opt }
)
: [];

const selectedOption = normalizedOptions.find((opt) => opt.value === value);

return (
<div className="inputwrapper" ref={dropdownRef} style={{ position: "relative" }}>
{label && <label>{label}</label>}
<button
type="button"
onClick={toggleDropdown}
className="dropbtn"
>
{selectedOption?.label || placeholder}
</button>

{isOpen && (
<ul
className="dropdown-menu"
>
{normalizedOptions.map((option) => (
<li
key={option.value}
onClick={() => handleOptionClick(option.value)}
style={{
padding: "0.5rem 1rem",
cursor: "pointer",
backgroundColor: value === option.value ? "#f0f0f0" : "#fff",
}}
>
{option.label}
</li>
))}
</ul>
)}
</div>
);
}

export default DropdownMenu;
45 changes: 45 additions & 0 deletions src/components/dropdown/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* Dropdown Button */
.dropbtn {
background-color: #3498DB;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}

/* Dropdown button on hover & focus */
.dropbtn:hover, .dropbtn:focus {
background-color: #2980B9;
}

/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
left: 0;
display: inline-block;
}

/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}

/* Links inside the dropdown */
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}

/* Change color of dropdown links on hover */
.dropdown-content a:hover {background-color: #ddd;}

/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {display:block;}
25 changes: 25 additions & 0 deletions src/components/form/numberInput/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

const NumberInput = ({ value, onChange, name, label, icon, type = 'number',placeholder}) => {

return (
<div className="inputwrapper">
{label && <label htmlFor={name}>{label}</label>}
<input
type={type}
name={name}
value={value}
onChange={onChange}
className={icon && 'input-has-icon'}
placeholder={placeholder}

onInput={(e) => {
if (e.target.value.length > 11) {
e.target.value = e.target.value.slice(0, 11);
}}}
/>
{icon && <span className="input-icon">{icon}</span>}
</div>
);
}

export default NumberInput;
11 changes: 7 additions & 4 deletions src/components/form/textInput/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useState } from 'react';

const TextInput = ({ value, onChange, name, label, icon, type = 'text' }) => {
const [input, setInput] = useState('');
const TextInput = ({ value, onChange, name, label, icon, type = 'text', placeholder }) => {
const [showpassword, setShowpassword] = useState(false);
const [input, setInput] = useState(value);
if (type === 'password') {
return (
<div className="inputwrapper">
Expand All @@ -11,9 +11,10 @@ const TextInput = ({ value, onChange, name, label, icon, type = 'text' }) => {
type={type}
name={name}
value={value}
placeholder = {placeholder}
onChange={(e) => {
onChange(e);
setInput(e.target.value);
setInput(e.target.value)
}}
/>
{showpassword && <input type="text" name={name} value={input} className="passwordreveal" />}
Expand All @@ -22,6 +23,7 @@ const TextInput = ({ value, onChange, name, label, icon, type = 'text' }) => {
onClick={(e) => {
e.preventDefault();
setShowpassword(!showpassword);

}}
>
<EyeLogo />
Expand All @@ -36,14 +38,15 @@ const TextInput = ({ value, onChange, name, label, icon, type = 'text' }) => {
type={type}
name={name}
value={value}
placeholder = {placeholder}
onChange={onChange}
className={icon && 'input-has-icon'}
/>
{icon && <span className="input-icon">{icon}</span>}
</div>
);
}
};
}

const EyeLogo = () => {
return (
Expand Down
2 changes: 1 addition & 1 deletion src/components/navigation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const Navigation = () => {
</NavLink>
</li>
<li>
<NavLink to="/">
<NavLink to="/cohorts">
<CohortIcon />
<p>Cohort</p>
</NavLink>
Expand Down
21 changes: 18 additions & 3 deletions src/components/posts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,32 @@ const Posts = () => {
const [posts, setPosts] = useState([]);

useEffect(() => {
getPosts().then(setPosts);
async function fetchPosts() {
try {
const posts = await getPosts();
setPosts(posts);
} catch (error) {
console.error('Error fetching posts:', error);
setPosts([]);
}
}
fetchPosts();
}, []);


return (
<>
{posts.map((post) => {
// Handle missing author gracefully
const authorName = post.author
? `${post.author.first_name || 'Unknown'} ${post.author.last_name || 'User'}`
: 'Unknown User';

return (
<Post
key={post.id}
name={`${post.author.firstName} ${post.author.lastName}`}
date={post.createdAt}
name={authorName}
date={post.createdAt || 'Unknown date'}
content={post.content}
comments={post.comments}
/>
Expand Down
Loading