-
-
+
+
+ {attestation?.name}
+
+
+
{metadata.data?.bio}
+
+
+
+ {!isLoading && appState === EAppState.VOTING && (
+
+
+ {state === EProjectState.DEFAULT && (
+
+ )}
+ {state === EProjectState.ADDED && (
+
+ )}
+ {state === EProjectState.SUBMITTED && (
+
+ )}
+
+
+ )}
-
-
-
-
);
};
diff --git a/src/features/projects/components/ProjectSelectButton.tsx b/src/features/projects/components/ProjectSelectButton.tsx
deleted file mode 100644
index 421c34b6..00000000
--- a/src/features/projects/components/ProjectSelectButton.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { AlbumIcon, CheckIcon, PlusIcon } from "lucide-react";
-import { type ComponentProps } from "react";
-import { tv } from "tailwind-variants";
-
-import { createComponent } from "~/components/ui";
-
-const ActionButton = createComponent(
- "button",
- tv({
- base: "flex h-6 w-6 items-center justify-center rounded-full border-2 border-transparent transition-colors bg-gray-100 dark:bg-gray-900",
- variants: {
- color: {
- default:
- "dark:border-white/50 dark:text-white hover:bg-gray-200 dark:hover:bg-gray-800 dark:hover:border-white",
- highlight: "hover:bg-white dark:hover:bg-gray-800 dark:border-white dark:text-white",
- green: "border-transparent border-gray-100 dark:border-gray-900 text-gray-500",
- },
- },
- defaultVariants: { color: "default" },
- }),
-);
-
-interface IProjectSelectButtonProps extends ComponentProps {
- state: 0 | 1 | 2;
-}
-
-export const ProjectSelectButton = ({ state, ...props }: IProjectSelectButtonProps): JSX.Element => {
- const { color, icon: Icon } = {
- 0: { color: "default", icon: PlusIcon },
- 1: { color: "highlight", icon: CheckIcon },
- 2: { color: "green", icon: AlbumIcon },
- }[state];
-
- return (
-
-
-
- );
-};
diff --git a/src/features/projects/components/Projects.tsx b/src/features/projects/components/Projects.tsx
index 362fa396..44955dfb 100644
--- a/src/features/projects/components/Projects.tsx
+++ b/src/features/projects/components/Projects.tsx
@@ -1,97 +1,83 @@
import clsx from "clsx";
-import { XIcon } from "lucide-react";
import Link from "next/link";
-import { useCallback } from "react";
import { InfiniteLoading } from "~/components/InfiniteLoading";
-import { SortFilter } from "~/components/SortFilter";
-import { Alert } from "~/components/ui/Alert";
-import { Button } from "~/components/ui/Button";
-import { config } from "~/config";
-import { useMaci } from "~/contexts/Maci";
-import { useResults } from "~/hooks/useResults";
+import { useSearchProjects } from "../hooks/useProjects";
import { useAppState } from "~/utils/state";
import { EAppState } from "~/utils/types";
-
-import { useSearchProjects } from "../hooks/useProjects";
-import { useSelectProjects } from "../hooks/useSelectProjects";
-
+import { EProjectState } from "../types";
+import { useResults } from "~/hooks/useResults";
+import { SortFilter } from "~/components/SortFilter";
import { ProjectItem, ProjectItemAwarded } from "./ProjectItem";
-import { ProjectSelectButton } from "./ProjectSelectButton";
+import { useMaci } from "~/contexts/Maci";
+import { useBallot } from "~/contexts/Ballot";
export const Projects = (): JSX.Element => {
const projects = useSearchProjects();
- const select = useSelectProjects();
const appState = useAppState();
- const { isRegistered, pollData } = useMaci();
+ const { pollData, pollId, isRegistered } = useMaci();
+ const { addToBallot, removeFromBallot, ballotContains, ballot } = useBallot();
const results = useResults(pollData);
- const handleAdd = useCallback(() => {
- select.add();
- }, [select]);
+ const handleAction = (e: Event, projectId: string) => {
+ e.preventDefault();
+
+ if (!ballotContains(projectId)) {
+ addToBallot(
+ [
+ {
+ projectId,
+ amount: 0,
+ },
+ ],
+ pollId,
+ );
+ } else {
+ removeFromBallot(projectId);
+ }
+ };
- const handleReset = useCallback(() => {
- select.reset();
- }, [select]);
+ const defineState = (projectId: string): EProjectState => {
+ if (!isRegistered) return EProjectState.UNREGISTERED;
+ else if (ballotContains(projectId) && ballot?.published)
+ return EProjectState.SUBMITTED;
+ else if (ballotContains(projectId) && !ballot?.published)
+ return EProjectState.ADDED;
+ else return EProjectState.DEFAULT;
+ };
return (
- {select.count > config.voteLimit && (
-
- You have exceeded your vote limit. You can only vote for {config.voteLimit} options.
-
- )}
-
-
-
-
-
-
-
-
-
+
(
-
- {isRegistered && !isLoading && appState === EAppState.VOTING ? (
-
-
{
- e.preventDefault();
- select.toggle(item.id);
- }}
+ renderItem={(item, { isLoading }) => {
+ return (
+
+ {!results.isLoading && appState === EAppState.RESULTS ? (
+
-
- ) : null}
-
- {!results.isLoading && appState === EAppState.RESULTS ? (
-
- ) : null}
-
-
-
- )}
+ ) : null}
+ handleAction(e, item.id)}
+ />
+
+ );
+ }}
/>
);
diff --git a/src/features/projects/components/VotingWidget.tsx b/src/features/projects/components/VotingWidget.tsx
new file mode 100644
index 00000000..4ffa1a5a
--- /dev/null
+++ b/src/features/projects/components/VotingWidget.tsx
@@ -0,0 +1,101 @@
+import { useMemo, useCallback, useState } from "react";
+
+import { useMaci } from "~/contexts/Maci";
+import { useBallot } from "~/contexts/Ballot";
+import { Input } from "~/components/ui/Input";
+import { Button } from "~/components/ui/Button";
+import { EButtonState } from "../types";
+
+export const VotingWidget = ({ projectId }: { projectId: string }) => {
+ const { pollId } = useMaci();
+ const { ballotContains, removeFromBallot, addToBallot } = useBallot();
+ const projectBallot = useMemo(
+ () => ballotContains(projectId),
+ [ballotContains, projectId],
+ );
+ const projectIncluded = useMemo(() => !!projectBallot, [projectBallot]);
+ const [amount, setAmount] = useState
(
+ projectBallot?.amount,
+ );
+
+ /**
+ * buttonState
+ * 0. this project is not included in the ballot before
+ * 1. this project is included in the ballot before
+ * 2. after onChange from a value to another value (original state is 1)
+ * 3. after edited
+ */
+ const [buttonState, setButtonState] = useState(
+ projectIncluded ? EButtonState.ADDED : EButtonState.DEFAULT,
+ );
+
+ const handleRemove = useCallback(() => {
+ removeFromBallot(projectId);
+ setAmount(undefined);
+ setButtonState(0);
+ }, [removeFromBallot]);
+
+ const handleInput = (e: Event) => {
+ setAmount(e.target?.value as number);
+
+ if (
+ buttonState === EButtonState.ADDED ||
+ buttonState === EButtonState.UPDATED
+ ) {
+ setButtonState(EButtonState.EDIT);
+ }
+ };
+
+ const handleButtonAction = () => {
+ if (!amount) return;
+
+ addToBallot([{ projectId, amount }], pollId);
+ if (buttonState === EButtonState.DEFAULT)
+ setButtonState(EButtonState.ADDED);
+ else setButtonState(EButtonState.UPDATED);
+ };
+
+ return (
+
+ {projectIncluded && (
+
+ Remove from My Ballot
+
+ )}
+
+
+ {buttonState === EButtonState.DEFAULT && (
+
+ )}
+ {buttonState === EButtonState.ADDED && (
+
+ votes added
+
+
+ )}
+ {buttonState === EButtonState.EDIT && (
+
+ )}
+ {buttonState === EButtonState.UPDATED && (
+
+ votes updated
+
+
+ )}
+
+
+ );
+};
diff --git a/src/features/projects/types.ts b/src/features/projects/types.ts
new file mode 100644
index 00000000..1ca21a80
--- /dev/null
+++ b/src/features/projects/types.ts
@@ -0,0 +1,46 @@
+export enum EContributionType {
+ CONTRACT_ADDRESS = "CONTRACT_ADDRESS",
+ GITHUB_REPO = "GIGHUB_REPO",
+ OTHER = "OTHER",
+}
+
+export enum EFundingSourceType {
+ OTHER = "OTHER",
+ RETROPGF_2 = "RETROPGF_2",
+ GOVERNANCE_FUND = "GOVERNANCE_FUND",
+ PARTNER_FUND = "PARTNER_FUND",
+ REVENUE = "REVENUE",
+}
+
+export enum EButtonState {
+ DEFAULT,
+ ADDED,
+ EDIT,
+ UPDATED,
+}
+
+export enum EProjectState {
+ UNREGISTERED,
+ DEFAULT,
+ ADDED,
+ SUBMITTED,
+}
+
+export interface ImpactMetrix {
+ url: string;
+ description: string;
+ number: number;
+}
+
+export interface ContributionLink {
+ url: string;
+ type: EContributionType;
+ description: string;
+}
+
+export interface FundingSource {
+ type: EFundingSourceType;
+ description: string;
+ currency: string;
+ amount: number;
+}
diff --git a/src/layouts/BaseLayout.tsx b/src/layouts/BaseLayout.tsx
index ee4f9bcc..c3a9aebf 100644
--- a/src/layouts/BaseLayout.tsx
+++ b/src/layouts/BaseLayout.tsx
@@ -2,7 +2,15 @@ import clsx from "clsx";
import Head from "next/head";
import { useRouter } from "next/router";
import { useTheme } from "next-themes";
-import { type ReactNode, type PropsWithChildren, createContext, useContext, useEffect, useMemo } from "react";
+import {
+ type ReactNode,
+ type PropsWithChildren,
+ createContext,
+ useContext,
+ useEffect,
+ useCallback,
+ useMemo,
+} from "react";
import { useAccount } from "wagmi";
import { Footer } from "~/components/Footer";
@@ -28,7 +36,9 @@ export interface LayoutProps {
requireAuth?: boolean;
eligibilityCheck?: boolean;
showBallot?: boolean;
-}
+ showInfo?: boolean;
+ showSubmitButton?: boolean;
+};
export const BaseLayout = ({
header = null,
@@ -50,12 +60,16 @@ export const BaseLayout = ({
const router = useRouter();
const { address, isConnecting } = useAccount();
- useEffect(() => {
+ const manageDisplay = useCallback(async () => {
if (requireAuth && !address && !isConnecting) {
- router.push("/");
+ await router.push("/");
}
}, [requireAuth, address, isConnecting, router]);
+ useEffect(() => {
+ manageDisplay();
+ }, [manageDisplay]);
+
const wrappedSidebar = {sidebarComponent};
const contextValue = useMemo(() => ({ eligibilityCheck, showBallot }), [eligibilityCheck, showBallot]);
@@ -91,11 +105,19 @@ export const BaseLayout = ({
-
-
+
{header}
-
-
+
{sidebar === "left" ? wrappedSidebar : null}
{
const { address } = useAccount();
const appState = useAppState();
+ const { ballot } = useBallot();
- const navLinks = [
- {
- href: "/projects",
- children: "Projects",
- },
- {
- href: "/info",
- children: "Info",
- },
- ];
+ const navLinks = useMemo(() => {
+ const navLinks = [
+ {
+ href: "/projects",
+ children: "Projects",
+ },
+ ];
- if (appState === EAppState.RESULTS) {
- navLinks.push({
- href: "/stats",
- children: "Stats",
- });
- }
+ if (ballot?.published) {
+ navLinks.push({
+ href: "/ballot/confirmation",
+ children: "My Ballot",
+ });
+ } else {
+ navLinks.push({
+ href: "/ballot",
+ children: "My Ballot",
+ });
+ }
- if (config.admin === address!) {
- navLinks.push(
- ...[
- {
- href: "/applications",
- children: "Applications",
- },
- {
- href: "/voters",
- children: "Voters",
- },
- ],
- );
- }
+ if (appState === EAppState.RESULTS) {
+ navLinks.push({
+ href: "/stats",
+ children: "Stats",
+ });
+ }
+
+ if (config.admin === address!) {
+ navLinks.push(
+ ...[
+ {
+ href: "/applications",
+ children: "Applications",
+ },
+ {
+ href: "/voters",
+ children: "Voters",
+ },
+ ],
+ );
+ }
+
+ return navLinks;
+ }, [ballot, appState, address]);
return (
}>
@@ -61,6 +77,31 @@ export const Layout = ({ children = null, ...props }: Props): JSX.Element => {
);
};
-export const LayoutWithBallot = ({ ...props }: Props): JSX.Element => (
-
} {...props} />
-);
+export function LayoutWithSidebar({ ...props }: Props) {
+ const { isRegistered } = useMaci();
+ const { address } = useAccount();
+ const { ballot } = useBallot();
+
+ return (
+
+ {props.showInfo && }
+ {props.showBallot && address && isRegistered && }
+ {props.showSubmitButton && ballot && ballot.votes.length > 0 && (
+
+
+
+
+ )}
+
+
+ }
+ {...props}
+ />
+ );
+}
diff --git a/src/pages/ballot/confirmation.tsx b/src/pages/ballot/confirmation.tsx
index 555d3252..d385edfd 100644
--- a/src/pages/ballot/confirmation.tsx
+++ b/src/pages/ballot/confirmation.tsx
@@ -1,17 +1,34 @@
+import { useRouter } from "next/router";
+import { useEffect, useState, useCallback } from "react";
+
import { useBallot } from "~/contexts/Ballot";
import { BallotConfirmation } from "~/features/ballot/components/BallotConfirmation";
import { Layout } from "~/layouts/DefaultLayout";
+import { Spinner } from "~/components/ui/Spinner";
const BallotConfirmationPage = (): JSX.Element | null => {
- const { ballot } = useBallot();
+ const [isLoading, setIsLoading] = useState
(true);
+
+ const { ballot, isLoading: isBallotLoading } = useBallot();
+ const router = useRouter();
+
+ const manageDisplay = useCallback(async () => {
+ if (isBallotLoading) return;
+
+ if (ballot.published) {
+ setIsLoading(false);
+ } else {
+ await router.push("/ballot");
+ }
+ }, [router, ballot]);
- if (!ballot) {
- return null;
- }
+ useEffect(() => {
+ manageDisplay();
+ }, [manageDisplay]);
return (
- +b.amount - +a.amount)} />
+ {isLoading ? : }
);
};
diff --git a/src/pages/ballot/index.tsx b/src/pages/ballot/index.tsx
index 34261506..cd4c9ba4 100644
--- a/src/pages/ballot/index.tsx
+++ b/src/pages/ballot/index.tsx
@@ -7,11 +7,10 @@ import { useAccount } from "wagmi";
import { Button } from "~/components/ui/Button";
import { Dialog } from "~/components/ui/Dialog";
import { Form } from "~/components/ui/Form";
-import { config } from "~/config";
import { useBallot } from "~/contexts/Ballot";
import { AllocationFormWrapper } from "~/features/ballot/components/AllocationList";
import { BallotSchema, type Vote } from "~/features/ballot/types";
-import { LayoutWithBallot } from "~/layouts/DefaultLayout";
+import { LayoutWithSidebar } from "~/layouts/DefaultLayout";
import { formatNumber } from "~/utils/formatNumber";
import { useAppState } from "~/utils/state";
import { EAppState } from "~/utils/types";
@@ -33,28 +32,23 @@ const ClearBallot = () => {
return (
<>
-
);
-const TotalAllocation = () => {
- const { sumBallot } = useBallot();
- const form = useFormContext<{ votes: Vote[] }>();
- const votes = form.watch("votes");
- const sum = sumBallot(votes);
-
- return
{`${formatNumber(sum)} ${config.tokenName}`}
;
-};
-
const BallotAllocationForm = () => {
const appState = useAppState();
- const { ballot } = useBallot();
-
- return (
-
-
Review your vote
-
-
Once you have reviewed your votes allocation, you can submit your vote.
+ const { ballot, sumBallot } = useBallot();
-
{ballot?.votes.length ? : null}
+ const sum = useMemo(
+ () => formatNumber(sumBallot(ballot?.votes)),
+ [ballot, sumBallot],
+ );
-
+ return (
+
+
My Ballot
+
+ Once you have reviewed your vote allocation, you can submit your ballot.
+
+
+ {ballot?.votes?.length ? : null}
+
+
-
- {ballot?.votes.length ? (
-
- ) : (
-
- )}
-
+ {ballot?.votes?.length ? (
+
+ ) : (
+
+ )}
-
);
-};
+}
const BallotPage = (): JSX.Element => {
const { address, isConnecting } = useAccount();
@@ -128,26 +117,31 @@ const BallotPage = (): JSX.Element => {
useEffect(() => {
if (!address && !isConnecting) {
- // eslint-disable-next-line no-console
- router.push("/").catch(console.error);
+ router.push("/").catch(console.log);
}
}, [address, isConnecting, router]);
- const votes = useMemo(() => ballot?.votes.sort((a, b) => b.amount - a.amount), [ballot]);
+ const votes = useMemo(
+ () => ballot?.votes?.sort((a, b) => b.amount - a.amount),
+ [ballot],
+ );
if (!votes) {
return
;
}
return (
-
-
+
);
-};
+}
export default BallotPage;
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 91e87ccf..669ea527 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -1,15 +1,8 @@
import { type GetServerSideProps } from "next";
-import { Layout } from "~/layouts/DefaultLayout";
-
-const ProjectsPage = (): JSX.Element =>
...;
-
-export default ProjectsPage;
-
-export const getServerSideProps: GetServerSideProps = async () =>
- Promise.resolve({
- redirect: {
- destination: "/projects",
- permanent: false,
- },
- });
+export const getServerSideProps: GetServerSideProps = async () => ({
+ redirect: {
+ destination: "/signup",
+ permanent: false,
+ },
+});
diff --git a/src/pages/projects/[projectId]/Project.tsx b/src/pages/projects/[projectId]/Project.tsx
index 713d857c..1e3da589 100644
--- a/src/pages/projects/[projectId]/Project.tsx
+++ b/src/pages/projects/[projectId]/Project.tsx
@@ -1,12 +1,8 @@
import { type GetServerSideProps } from "next";
-import { ProjectAddToBallot } from "~/features/projects/components/AddToBallot";
-import { ProjectAwarded } from "~/features/projects/components/ProjectAwarded";
+import { LayoutWithSidebar } from "~/layouts/DefaultLayout";
import ProjectDetails from "~/features/projects/components/ProjectDetails";
import { useProjectById } from "~/features/projects/hooks/useProjects";
-import { LayoutWithBallot } from "~/layouts/DefaultLayout";
-import { useAppState } from "~/utils/state";
-import { EAppState } from "~/utils/types";
export interface IProjectDetailsProps {
projectId?: string;
@@ -14,19 +10,18 @@ export interface IProjectDetailsProps {
const ProjectDetailsPage = ({ projectId = "" }: IProjectDetailsProps): JSX.Element => {
const projects = useProjectById(projectId);
- const { name } = projects.data?.[0] ?? {};
- const appState = useAppState();
+ const { name } = projects.data?.[0] ?? {};;
- const action =
- appState === EAppState.RESULTS ? (
-
- ) : (
-
- );
return (
-
-
-
+
+
+
);
};
diff --git a/src/pages/projects/index.tsx b/src/pages/projects/index.tsx
index ab50c306..24d7f967 100644
--- a/src/pages/projects/index.tsx
+++ b/src/pages/projects/index.tsx
@@ -1,10 +1,12 @@
+import { LayoutWithSidebar } from "~/layouts/DefaultLayout";
import { Projects } from "~/features/projects/components/Projects";
-import { LayoutWithBallot } from "~/layouts/DefaultLayout";
-const ProjectsPage = (): JSX.Element => (
-
-
-
-);
+const ProjectsPage = (): JSX.Element => {
+ return (
+
+
+
+ );
+}
export default ProjectsPage;
diff --git a/src/pages/signup/index.tsx b/src/pages/signup/index.tsx
new file mode 100644
index 00000000..fc4ba519
--- /dev/null
+++ b/src/pages/signup/index.tsx
@@ -0,0 +1,49 @@
+import { useAccount } from "wagmi";
+import Link from "next/link";
+import { format } from "date-fns";
+
+import { Layout } from "~/layouts/DefaultLayout";
+import { config } from "~/config";
+import { ConnectButton } from "~/components/ConnectButton";
+import { JoinButton } from "~/components/JoinButton";
+import { Info } from "~/components/Info";
+import { EligibilityDialog } from "~/components/EligibilityDialog";
+import { useMaci } from "~/contexts/Maci";
+import { Button } from "~/components/ui/Button";
+
+const SignupPage = (): JSX.Element => {
+ const { isConnected } = useAccount();
+ const { isRegistered } = useMaci();
+
+ return (
+
+
+
+
+
+ {config.eventName.toUpperCase()}
+
+
+ {config.roundId.toUpperCase()}
+
+
+ {format(config.startsAt, "d MMMM, yyyy")}
+ -
+ {format(config.resultsAt, "d MMMM, yyyy")}
+
+ {isConnected && isRegistered && (
+
+ View projects
+
+ )}
+ {isConnected && !isRegistered &&
}
+ {!isConnected &&
}
+
+
+
+
+
+ );
+}
+
+export default SignupPage;
diff --git a/src/providers/index.tsx b/src/providers/index.tsx
index 506f65d2..bc08499b 100644
--- a/src/providers/index.tsx
+++ b/src/providers/index.tsx
@@ -1,22 +1,49 @@
-import { type Chain, getDefaultConfig, RainbowKitProvider } from "@rainbow-me/rainbowkit";
+import {
+ type Chain,
+ getDefaultConfig,
+ RainbowKitProvider,
+ type Theme,
+ lightTheme,
+} from "@rainbow-me/rainbowkit";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ThemeProvider } from "next-themes";
import { useMemo, type PropsWithChildren } from "react";
import { http, WagmiProvider } from "wagmi";
+
import { Toaster } from "~/components/Toaster";
import * as appConfig from "~/config";
import { BallotProvider } from "~/contexts/Ballot";
import { MaciProvider } from "~/contexts/Maci";
-export const Providers = ({ children }: PropsWithChildren): JSX.Element => {
+const theme = lightTheme();
+
+const customTheme: Theme = {
+ blurs: {
+ ...theme.blurs,
+ },
+ colors: {
+ ...theme.colors,
+ },
+ fonts: {
+ body: "Share Tech Mono",
+ },
+ radii: {
+ ...theme.radii,
+ },
+ shadows: {
+ ...theme.shadows,
+ },
+};
+
+export function Providers({ children }: PropsWithChildren) {
const { config, queryClient } = useMemo(() => createWagmiConfig(), []);
return (
-
+
{children}
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 80419286..e4a35015 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -10,3 +10,48 @@
-ms-overflow-style: none;
scrollbar-width: 0;
}
+
+@layer base {
+ @font-face {
+ font-family: "Share Tech Mono";
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/fonts/Share_Tech_Mono.woff2) format("woff2");
+ }
+
+ @font-face {
+ font-family: "DM Sans";
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(/fonts/DM_Sans.woff2) format("woff2");
+ }
+
+ html {
+ font-family: "Share Tech Mono", "DM Sans";
+ }
+
+ h1 {
+ font-size: 60px;
+ font-family: "Share Tech Mono";
+ }
+
+ h2 {
+ font-size: 40px;
+ }
+
+ h3 {
+ font-family: "Share Tech Mono";
+ font-size: 32px;
+ color: black;
+ text-transform: uppercase;
+ }
+
+ h4 {
+ font-size: 16px;
+ font-weight: 800;
+ text-transform: uppercase;
+ color: #888888;
+ }
+}
diff --git a/src/utils/types.ts b/src/utils/types.ts
index c145313f..2bf5bc62 100644
--- a/src/utils/types.ts
+++ b/src/utils/types.ts
@@ -1,8 +1,13 @@
export enum EAppState {
LOADING = "LOADING",
APPLICATION = "APPLICATION",
- REVIEWING = "REVIEWING",
VOTING = "VOTING",
- RESULTS = "RESULTS",
TALLYING = "TALLYING",
+ RESULTS = "RESULTS",
+}
+
+export enum EInfoCardState {
+ PASSED = "PASSED",
+ ONGOING = "ONGOING",
+ UPCOMING = "UPCOMING",
}
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 2884f0af..a8dc0538 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -32,6 +32,37 @@ const customColors = {
highlight: {
600: "#F3CF00",
},
+ gray: {
+ 50: "#F6F6F6",
+ 100: "#E7E7E7",
+ 200: "#D1D1D1",
+ 300: "#B0B0B0",
+ 400: "#888888",
+ 500: "#6D6D6D",
+ 600: "#5D5D5D",
+ 700: "#4F4F4F",
+ 800: "#454545",
+ 900: "#3D3D3D",
+ 950: "#0B0B0B",
+ },
+ blue: {
+ 50: "#F0F7FE",
+ 100: "#DEECFB",
+ 200: "#C4E0F9",
+ 300: "#9BCCF5",
+ 400: "#6BB1EF",
+ 500: "#579BEA",
+ 600: "#3476DC",
+ 700: "#2B62CA",
+ 800: "#2950A4",
+ 900: "#264682",
+ 950: "#1B2B50",
+ },
+ black: "#0B0B0B",
+ darkGray: "#5E5E5E",
+ lightGray: "#CDCDCD",
+ green: "#00FF00",
+ red: "#EF4444",
};
export default {
@@ -42,10 +73,14 @@ export default {
colors: {
...colors,
...customColors,
- gray: colors.stone,
},
fontFamily: {
- sans: ["var(--font-inter)", ...theme.fontFamily.sans],
+ sans: ["DM Sans", ...theme.fontFamily.sans],
+ mono: ["Share Tech Mono", ...theme.fontFamily.mono],
+ },
+ width: {
+ "112": "28rem",
+ "128": "32rem",
},
},
},