Skip to content

Commit

Permalink
Noob branch (#24)
Browse files Browse the repository at this point in the history
* wagmi hooks, lots of notes

* isOwner update

* changes to get login flow to check for isOwner and isEmployee - working

* fix bug in isOwner

* Success: can add/remove employees

* add paySingleEmployee, edit addEmployee

* edits to prepare for presentation

* readme

---------

Co-authored-by: Spencer Schoeneman <[email protected]>
Co-authored-by: Spencer Schoeneman <[email protected]>
  • Loading branch information
3 people authored Jan 5, 2024
1 parent 74e0747 commit 302f0dc
Show file tree
Hide file tree
Showing 23 changed files with 710 additions and 379 deletions.
87 changes: 19 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,78 +1,29 @@
# 🏗 Scaffold-ETH 2
# HoneyBadgerHR & MVMT Payroll
HoneyBadgerHR introduces the MVMT Payroll system, a Web3 solution that modernizes payroll processes using blockchain technology. This system empowers employers with flexible payroll management and incentivizes employees through an innovative KPI Raffle System.

<h4 align="center">
<a href="https://docs.scaffoldeth.io">Documentation</a> |
<a href="https://scaffoldeth.io">Website</a>
</h4>
# MVMT Payroll Smart Contract
The MVMT Payroll Smart Contract is designed to allow employers to execute payroll on multiple chains, providing employees the freedom to receive their earnings on any supported blockchain. This flexibility ensures that payroll can adapt to the diverse preferences of a global workforce.

🧪 An open-source, up-to-date toolkit for building decentralized applications (dapps) on the Ethereum blockchain. It's designed to make it easier for developers to create and deploy smart contracts and build user interfaces that interact with those contracts.
# Raffle Smart Contract
The Raffle Smart Contract is developed as a tool for employee engagement, allowing companies to hold raffles and reward employees. This feature aims to boost morale and encourage productivity by offering incentives in the form of digital assets.

⚙️ Built using NextJS, RainbowKit, Hardhat, Wagmi, and Typescript.
# Technologies Used
* Scaffold-ETH-3: Our project is built on top of Scaffold-ETH-3, which provided us with a robust development framework to create Ethereum-based applications efficiently.
* Dashboard Template (https://github.com/srobbin01/daisyui-admin-dashboard-template): The user interface leverages the daisyUI admin dashboard template, which offers a clean and modern UI for our front-end.
* Chainlink CCIP: Payroll.sol & TonkenTransferor.sol use CCIP to send tokens across chains
* Chainlink VRF & Automation: Raffle.sol pulls a random number from VRF to pick a winner of the raffle and is set up with Automation to pull the random number automatically once a raffle has ended.

-**Contract Hot Reload**: Your frontend auto-adapts to your smart contract as you edit it.
- 🔥 **Burner Wallet & Local Faucet**: Quickly test your application with a burner wallet and local faucet.
- 🔐 **Integration with Wallet Providers**: Connect to different wallet providers and interact with the Ethereum network.

![Debug Contracts tab](https://github.com/scaffold-eth/scaffold-eth-2/assets/55535804/1171422a-0ce4-4203-bcd4-d2d1941d198b)

## Requirements

Before you begin, you need to install the following tools:

- [Node (v18 LTS)](https://nodejs.org/en/download/)
- Yarn ([v1](https://classic.yarnpkg.com/en/docs/install/) or [v2+](https://yarnpkg.com/getting-started/install))
- [Git](https://git-scm.com/downloads)

## Quickstart

To get started with Scaffold-ETH 2, follow the steps below:

1. Clone this repo & install dependencies

```
git clone https://github.com/scaffold-eth/scaffold-eth-2.git
cd scaffold-eth-2
yarn install
```

2. Run a local network in the first terminal:
## Quick Start
To get started with HoneyBadgerHR:

```
yarn chain
```

This command starts a local Ethereum network using Hardhat. The network runs on your local machine and can be used for testing and development. You can customize the network configuration in `hardhat.config.ts`.
# Clone the repository
git clone https://github.com/your-repo-link
3. On a second terminal, deploy the test contract:

```
yarn deploy
```

This command deploys a test smart contract to the local network. The contract is located in `packages/hardhat/contracts` and can be modified to suit your needs. The `yarn deploy` command uses the deploy script located in `packages/hardhat/deploy` to deploy the contract to the network. You can also customize the deploy script.

4. On a third terminal, start your NextJS app:
# Install dependencies
yarn install
```
# Start the development server
yarn start
```

Visit your app on: `http://localhost:3000`. You can interact with your smart contract using the `Debug Contracts` page. You can tweak the app config in `packages/nextjs/scaffold.config.ts`.

Run smart contract test with `yarn hardhat:test`
- Edit your smart contract `YourContract.sol` in `packages/hardhat/contracts`
- Edit your frontend in `packages/nextjs/pages`
- Edit your deployment scripts in `packages/hardhat/deploy`

## Documentation

Visit our [docs](https://docs.scaffoldeth.io) to learn how to start building with Scaffold-ETH 2.

To know more about its features, check out our [website](https://scaffoldeth.io).

## Contributing to Scaffold-ETH 2

We welcome contributions to Scaffold-ETH 2!

Please see [CONTRIBUTING.MD](https://github.com/scaffold-eth/scaffold-eth-2/blob/main/CONTRIBUTING.md) for more information and guidelines for contributing to Scaffold-ETH 2.
```
8 changes: 4 additions & 4 deletions packages/nextjs/components/MetaHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ type MetaHeaderProps = {
const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}/` : "/";

export const MetaHeader = ({
title = "Scaffold-ETH 2 App",
description = "Built with 🏗 Scaffold-ETH 2",
image = "thumbnail.jpg",
title = "Honey Badger HR",
description = "CCIP Powered Payroll",
image = "honey-badger-hr.png",
twitterCard = "summary_large_image",
children,
}: MetaHeaderProps) => {
Expand Down Expand Up @@ -45,7 +45,7 @@ export const MetaHeader = ({
</>
)}
{twitterCard && <meta name="twitter:card" content={twitterCard} />}
<link rel="icon" type="image/png" sizes="32x32" href="/favicon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/honey-badger-hr.png" />
{children}
</Head>
);
Expand Down
42 changes: 22 additions & 20 deletions packages/nextjs/components/dash-wind/containers/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
import React, { useEffect, useState } from "react";
// import Image from "next/image";
import Link from "next/link";
// import Link from "next/link";
import { useRouter } from "next/router";
import { openRightDrawer } from "../features/common/rightDrawerSlice";
import { RIGHT_DRAWER_TYPES } from "../utils/globalConstantUtil";
// import { openRightDrawer } from "../features/common/rightDrawerSlice";
// import { RIGHT_DRAWER_TYPES } from "../utils/globalConstantUtil";
import { themeChange } from "theme-change";
import { Address, createWalletClient, custom } from "viem";
import { polygonMumbai } from "viem/chains";
import Bars3Icon from "@heroicons/react/24/outline/Bars3Icon";
import BellIcon from "@heroicons/react/24/outline/BellIcon";
// import BellIcon from "@heroicons/react/24/outline/BellIcon";
import MoonIcon from "@heroicons/react/24/outline/MoonIcon";
import SunIcon from "@heroicons/react/24/outline/SunIcon";
import { setIsAdmin, setIsConnected } from "~~/auth/authSlice";
import { setIsConnected } from "~~/auth/authSlice";
// import { setIsAdmin, setIsConnected } from "~~/auth/authSlice";
import { web3auth } from "~~/auth/web3auth";
// import UserIcon from "@heroicons/react/24/outline/UserIcon";
import { MyState, useMyDispatch, useMySelector } from "~~/components/dash-wind/app/store";
import { Address as AddressDisplay } from "~~/components/web-3-crew/Address";

function Header() {
const dispatch = useMyDispatch();
const { noOfNotifications, pageTitle } = useMySelector((state: MyState) => state.header);
const { isAdmin } = useMySelector((state: MyState) => state.auth);
const { pageTitle } = useMySelector((state: MyState) => state.header);
// const { noOfNotifications, pageTitle } = useMySelector((state: MyState) => state.header);
// const { isAdmin } = useMySelector((state: MyState) => state.auth);
const [currentTheme, setCurrentTheme] = useState(
typeof window !== "undefined" ? localStorage.getItem("theme") : null,
);
Expand Down Expand Up @@ -51,7 +53,7 @@ function Header() {

async function getAccounts() {
if (!web3auth.provider) {
console.log("from login - getAccounts: provider not defined");
// console.log("from login - getAccounts: provider not defined");
return;
}
const client = createWalletClient({
Expand All @@ -67,19 +69,19 @@ function Header() {
}

// Opening right sidebar for notification
const openNotification = () => {
dispatch(openRightDrawer({ header: "Notifications", bodyType: RIGHT_DRAWER_TYPES.NOTIFICATION }));
};
// const openNotification = () => {
// dispatch(openRightDrawer({ header: "Notifications", bodyType: RIGHT_DRAWER_TYPES.NOTIFICATION }));
// };

async function logoutUser() {
await web3auth.logout();
dispatch(setIsConnected({ isConnected: false }));
router.push("/login");
}

function toggleIsAdmin() {
dispatch(setIsAdmin({ isAdmin: !isAdmin }));
}
// function toggleIsAdmin() {
// dispatch(setIsAdmin({ isAdmin: !isAdmin }));
// }

return (
<>
Expand All @@ -93,9 +95,9 @@ function Header() {
</div>

<div className="order-last">
<button className="btn btn-ghost mr-4 btn-circle" onClick={() => toggleIsAdmin()}>
{/* <button className="btn btn-ghost mr-4 btn-circle" onClick={() => toggleIsAdmin()}>
Toggle isAdmin
</button>
</button> */}
{/* Multiple theme selection, uncomment this if you want to enable multiple themes selection,
also includes corporate and retro themes in tailwind.config file */}

Expand Down Expand Up @@ -123,14 +125,14 @@ function Header() {
</label>

{/* Notification icon */}
<button className="btn btn-ghost ml-4 btn-circle" onClick={() => openNotification()}>
{/* <button className="btn btn-ghost ml-4 btn-circle" onClick={() => openNotification()}>
<div className="indicator">
<BellIcon className="h-6 w-6" />
{noOfNotifications > 0 ? (
<span className="indicator-item badge badge-secondary badge-sm">{noOfNotifications}</span>
) : null}
</div>
</button>
</button> */}

{/* Profile icon, opening menu on click */}
<div className="dropdown dropdown-end ml-4">
Expand All @@ -144,7 +146,7 @@ function Header() {
tabIndex={0}
className="menu menu-compact dropdown-content mt-3 p-2 shadow bg-base-100 rounded-box w-52"
>
<li className="justify-between">
{/* <li className="justify-between">
<Link href="/dapp/settings-profile">
Profile Settings
<span className="badge">New</span>
Expand All @@ -153,7 +155,7 @@ function Header() {
<li className="">
<Link href="/dapp/settings-billing">Bill History</Link>
</li>
<div className="divider mt-0 mb-0"></div>
<div className="divider mt-0 mb-0"></div> */}
<li>
<a onClick={logoutUser}>Logout</a>
</li>
Expand Down
56 changes: 29 additions & 27 deletions packages/nextjs/components/dash-wind/containers/LeftSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import Link from "next/link";
import { useRouter } from "next/router";
import { adminRoutes, userRoutes } from "../routes/sidebar";
import SidebarSubmenu from "./SidebarSubmenu";
// import SidebarSubmenu from "./SidebarSubmenu";
import { MyState, useMySelector } from "~~/components/dash-wind/app/store";

// import XMarkIcon from "@heroicons/react/24/outline/XMarkIcon";
Expand Down Expand Up @@ -35,37 +35,39 @@ function LeftSidebar() {
</button> */}

<li className="mb-2 font-semibold text-xl">
<Link href={"/dapp/welcome"}>
<img className="mask mask-squircle w-10" src="/logo192.png" alt="DashWind Logo" />
DashWind
</Link>{" "}
{/* <Link href={"/dapp/welcome"}> */}
<div className="hover:cursor-default hover:bg-inherit">
<img className="mask mask-squircle w-10" src="/honey-badger-hr.png" alt="Honey Badger Logo" />
Honey Badger HR
</div>
{/* </Link>{" "} */}
</li>
{routes.map((route, k) => {
return (
<li className="" key={k}>
{route.submenu ? (
{/* {route.submenu ? (
<SidebarSubmenu {...route} />
) : (
<Link legacyBehavior href={route.path}>
<a
className={
router.pathname === route.path ||
(route.path === "/dapp/employees" && /\/employee\/./i.test(router.pathname))
? "font-semibold bg-base-200 "
: "font-normal"
}
>
{<route.icon className={route.className} />} {route.name}
{router.pathname === route.path ||
(route.path === "/dapp/employees" && /\/employee\/./i.test(router.pathname)) ? (
<span
className="absolute inset-y-0 left-0 w-1 rounded-tr-md rounded-br-md bg-primary"
aria-hidden="true"
></span>
) : null}
</a>
</Link>
)}
) : ( */}
<Link legacyBehavior href={route.path}>
<a
className={
router.pathname === route.path ||
(route.path === "/dapp/employees" && /\/employee\/./i.test(router.pathname))
? "font-semibold bg-base-200 "
: "font-normal"
}
>
{<route.icon className={route.className} />} {route.name}
{router.pathname === route.path ||
(route.path === "/dapp/employees" && /\/employee\/./i.test(router.pathname)) ? (
<span
className="absolute inset-y-0 left-0 w-1 rounded-tr-md rounded-br-md bg-primary"
aria-hidden="true"
></span>
) : null}
</a>
</Link>
{/* )} */}
</li>
);
})}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CONFIRMATION_MODAL_CLOSE_TYPES } from "../../../utils/globalConstantUtil";
import { deleteLead } from "../../leads/leadSlice";
// import { deleteLead } from "../../leads/leadSlice";
import { deleteEmployee } from "../../employees/employeesSlice";
import { showNotification } from "../headerSlice";
// import axios from "axios";
import { useMyDispatch } from "~~/components/dash-wind/app/store";
Expand All @@ -16,10 +17,10 @@ function ConfirmationModalBody({ extraObject, closeModal }: props) {
const { message, type, index } = extraObject;

const proceedWithYes = async () => {
if (type === CONFIRMATION_MODAL_CLOSE_TYPES.LEAD_DELETE) {
if (type === CONFIRMATION_MODAL_CLOSE_TYPES.EMPLOYEE_DELETE) {
// positive response, call api or dispatch redux function
dispatch(deleteLead({ index }));
dispatch(showNotification({ message: "Lead Deleted!", status: 1 }));
dispatch(deleteEmployee({ index }));
dispatch(showNotification({ message: "Employee Deleted!", status: 1 }));
}
closeModal();
};
Expand Down
Loading

0 comments on commit 302f0dc

Please sign in to comment.