Skip to content
Open
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ dist-ssr
.amplify
amplify_outputs*
amplifyconfiguration*

# dotenv files
.env
.env.*
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/png" href="/helpful-logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<title>Dashboard - Helpful Engineering</title>
</head>
<body>
<div id="root"></div>
Expand Down
2,012 changes: 1,956 additions & 56 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,21 @@
"test": "vitest run --passWithNoTests"
},
"dependencies": {
"@auth0/auth0-react": "^2.3.0",
"@aws-amplify/ui-react": "^6.5.5",
"@iconify/react": "^6.0.0",
"@types/react-bootstrap": "^0.32.37",
"@types/react-modal": "^3.16.3",
"@types/react-router-dom": "^5.3.3",
"aws-amplify": "^6.6.6",
"bootstrap": "^5.3.5",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-bootstrap": "^2.10.9",
"react-dom": "^18.2.0",
"react-markdown": "^10.1.0",
"react-modal": "^3.16.3",
"react-router-dom": "^7.5.3",
"react-select": "^5.10.1"
},
"devDependencies": {
"@aws-amplify/backend": "^1.5.0",
Expand Down
30 changes: 30 additions & 0 deletions public/Contributor-Agreement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Contributor Agreement

Thank you for joining the Helpful community!

Helpful Engineering is an international, open-source community incubator focused on mobilizing people to help solve critical issues. With thousands of volunteers worldwide, our mission is to support projects through innovations in engineering, community resources, software, and manufacturing. All volunteers **must be at least 18 years old.** If you are under the age of eighteen, your parent or guardian must agree to this Contributor Agreement on your behalf.

Whether you are here to create a new project or offer support to an existing one, we’re happy you showed up. In order for us to stay focused on our mission and to do our best work, here are our Code of Conduct and Community Rules:

**Our Code of Conduct.** You agree to adopt and uphold the Helpful Code of Conduct while working with and representing the Helpful community:

- **BE KIND.** We expect everyone to act with mutual respect, dignity, and compassion. This includes abstaining from prejudicial words, or actions, involving race, gender, class, sexual orientation, gender presentation, physical ability, or religious affiliations.
- **BE COMMUNICATIVE**. Transparency is key, and you will be asked for updates on your role and activities in the community. Following existing workflows and having frequent communication keeps everyone on the same page and decreases the likelihood of critical mistakes, misunderstandings, or duplicated work.
- **BE THOUGHTFUL.** We love new ideas and new collaborations, but our community values making decisions carefully. Large decisions should be made with input from others and not unilaterally! If you have questions, ask and let’s find a solution.
- **BE ACCOUNTABLE.** Mistakes happen even with the best of intentions. If you say you’re going to do something, do it. If you can’t do it on time, inform your co-collaborators in a timely manner so that others can step in and support you.
- **BE TRUSTWORTHY.** We stress safeguarding community resources including sensitive information, passwords, personal information, and other internal data. This means you won’t divert or utilize Helpful resources or relationships towards another effort – public, or private. If you become aware of a conflict of interest, you will timely speak to an Officer or Board Director of Helpful to discuss the way forward.
- **BE CONSCIENTIOUS**. The Helpful community is counting on you to be professional. Helpful consists of many volunteers giving their time and effort. Please leave your workspace, files, and tools in an orderly fashion such that they are accessible to other members of the community. If you decide to move on from Helpful, please share your contact information with and assist the next person who will continue the excellent work that you’ve already done.
- **BE RESPECTFUL.** Many people are volunteering their time, tools, and other resources to make this effort come together, so please be respectful of individuals, their time, tools and resources. Make an effort to be professional and helpful.
- **BE HELPFUL.** Our primary goal is to do work that is helpful!

## Our Community Rules

- You understand that you are not considered an employee of Helpful and will not be entitled to receive any employee benefits.
- You are responsible for the contributions you make to the Helpful community, including any content which you may disseminate using Helpful resources (your “**Content**”).
- Although you retain ownership rights in your Content, you understand and acknowledge that, when you disseminate your Content using Helpful resources, it becomes Helpful Work Product (as defined below) and, as such, it becomes subject to an open-source license.
- “**Helpful Work Product**” is all documents, data, work product and/or other materials, including any intellectual property rights therein, that are developed or prepared by you, other Helpful volunteers, or other third parties using Helpful resources.
- You have an obligation to offer Helpful Work Product to the public using an open-source license compliant with the Helpful Licensing Guide which is available at <https://helpfulengineering.org/licensing-guide/> (the “**Helpful Licensing Guide**”).
- **If you are working on an existing project using Helpful resources**, there must be a license compliant with the Helpful Licensing Guide set forth in the applicable repository for that project. If this is the case, you have an obligation to comply with that license. If this is not the case, you have an obligation to add a compliant license.
- **If you are establishing a new project using Helpful resources**, you have an obligation to use and comply with a license compliant with the Helpful Licensing Guide for that project and to publish such license in any applicable repository.
- You hereby waive any and all claims you may now or hereafter have in any jurisdiction to so-called “moral rights” or rights of droit moral with respect to Helpful Work Product, to the extent such rights would conflict with this Agreement.
- Lastly, in order to ensure that it remains open source and properly credited, all Helpful Work Product must be maintained on and reflected in a Helpful-designated and maintained repository.
Binary file added public/helpful-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion public/vite.svg

This file was deleted.

1 change: 0 additions & 1 deletion src/assets/react.svg

This file was deleted.

10 changes: 10 additions & 0 deletions src/auth0/login.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { useAuth0 } from "@auth0/auth0-react";
import React from "react";

const LoginButton: React.FC = () => {
const { loginWithRedirect } = useAuth0();

return <button onClick={() => loginWithRedirect()} className="login-button header-button">Log In</button>;
};

export default LoginButton;
17 changes: 17 additions & 0 deletions src/auth0/logout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useAuth0 } from "@auth0/auth0-react";
import React from "react";

const LogoutButton: React.FC = () => {
const { logout } = useAuth0();

return <button
onClick={() =>
logout({ logoutParams: { returnTo: window.location.origin } })
}
className="logout-button header-button"
>
Log Out
</button>
};

export default LogoutButton;
29 changes: 29 additions & 0 deletions src/auth0/profile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useAuth0 } from "@auth0/auth0-react";
import React from "react";

interface User {
picture?: string;
name?: string;
email?: string;
}

const Profile: React.FC = () => {
const { user, isAuthenticated, isLoading } = useAuth0<User>();

if (isLoading) {
return <div>Loading ...</div>;
}

return (
isAuthenticated &&
user && (
<div>
<img src={user.picture} alt={user.name} />
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
)
);
};

export default Profile;
18 changes: 18 additions & 0 deletions src/auth0/signup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useAuth0 } from "@auth0/auth0-react";

const SignupButton = () => {
const { loginWithRedirect } = useAuth0();

const handleSignup = () => {
loginWithRedirect({
authorizationParams: {
screen_hint: "signup",
},
appState: { returnTo: "/signup" }
});
};

return <button onClick={handleSignup} className="header-button signup-button">Sign Up</button>;
};

export default SignupButton;
16 changes: 16 additions & 0 deletions src/components/BackNavigationFix.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// This function is used to fix the back navigation issue after signup where navigating back in history can show a stale or invalid Auth0 transaction page, leading to errors. This is a known issue when using auth0 and SPA. Need further testing as it doesn't seem to solve this problem.

import { useEffect } from "react";

export default function BackNavigationFix() {
useEffect(() => {
const handlePageShow = (event: PageTransitionEvent) => {
if (event.persisted) {
window.location.reload();
}
};
window.addEventListener("pageshow", handlePageShow);
return () => window.removeEventListener("pageshow", handlePageShow);
}, []);
return null;
}
2 changes: 1 addition & 1 deletion src/components/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import './Card.css';
import './styles/Card.css';

interface CardProps {
title: string;
Expand Down
19 changes: 19 additions & 0 deletions src/components/DownArrow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Icon } from '@iconify/react';
import React from 'react';

interface DownArrowProps {
style?: React.CSSProperties;
size?: number | string;
color?: string;
}

const DownArrow: React.FC<DownArrowProps> = ({ style, size = 24, color = 'black' }) => (
<Icon
icon="ic:outline-arrow-drop-down"
width={size}
height={size}
style={{ color, ...style }}
/>
);

export default DownArrow;
73 changes: 0 additions & 73 deletions src/components/Header.css

This file was deleted.

84 changes: 71 additions & 13 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,87 @@
import React from 'react';
import './Header.css';
import helpfulIcon from '../assets/helpful_icon.png';
import profileIcon from '../assets/profile_icon.png';
import React, { useState, useEffect, useRef } from "react";
import { useAuth0 } from "@auth0/auth0-react";
import DownArrow from "./DownArrow.tsx";
import helpfulIcon from "../assets/helpful_icon.png";
import profileIcon from "../assets/profile_icon.png";
import LogoutButton from "../auth0/logout";
import LoginButton from "../auth0/login";
import "./styles/Header.css";

interface HeaderProps {
onProfileClick?: () => void;
}

const Header: React.FC<HeaderProps> = () => {
const { isAuthenticated, user } = useAuth0();

const menuRef = useRef<HTMLDivElement>(null);

useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
setMenuOpen(false);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);


const [menuOpen, setMenuOpen] = useState(false);

const Header: React.FC = () => {
return (
<header className="header-container">
<nav className="header-nav">
<div className="nav-links">
<div className="logo-section">
<img src={helpfulIcon} alt="Helpful Icon" className="helpful-icon" />
<a href="#about">About</a>
</div>
<div className="nav-links">
<a href="#about">
About
<DownArrow />
</a>
<a href="#volunteer">Volunteer</a>
<a href="#partners">Partners</a>
<a href="#research">Research</a>
<a href="#ourwork">Our Work</a>
<a href="#events">Events</a>
<a href="#blog">Blog</a>
<a href="#contact">Contact</a>
</div>

<div className="nav-buttons">
<button className="login-button">Login</button>
<button className="signup-button">Sign Up</button>
<img src={profileIcon} alt="Profile Icon" className="profile-icon" />
<div className="nav-buttons">
<button className="login-button header-button">Shop Now</button>
<button className="header-button bg-gray">Donate</button>
</div>
<div ref={menuRef} className="profile-menu-container" onClick={() => setMenuOpen(!menuOpen)} style={{ cursor: "pointer" }}>
<div
className="profile-menu-container"
onClick={() => setMenuOpen(!menuOpen)}
style={{ cursor: "pointer" }}
>
<img
src={
isAuthenticated && user?.picture ? user.picture : profileIcon
}
alt="Profile Icon"
className="profile-icon"
/>
<DownArrow />
{menuOpen && (
<div className="submenu">
<a href="/profile">Profile</a>
<a href="/dashboard">Dashboard</a>
{!isAuthenticated && <LoginButton />}
{isAuthenticated && <LogoutButton />}
</div>
)}
</div>
</div>
</div>
</nav>
</header>
);
};

export default Header;
export default Header;
Loading