Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:greenpill-dev-guild/impact-frame…
Browse files Browse the repository at this point in the history
…work-backend into op-season-5
  • Loading branch information
Oba-One committed Sep 21, 2024
2 parents d85b36f + da3f463 commit c9cc6de
Show file tree
Hide file tree
Showing 21 changed files with 13,546 additions and 6,317 deletions.
3 changes: 3 additions & 0 deletions packages/client/graphql.config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
schema:
- https://sepolia.easscan.org/graphql
documents: '**/*.graphql'
38 changes: 19 additions & 19 deletions packages/client/orval.config.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import {defineConfig} from 'orval';
import { defineConfig } from "orval";

export default defineConfig({
"op-agora": {
input: 'https://vote.optimism.io/api/v1/spec',
output: {
mode: 'split',
target: './src/__generated__/api/agora.ts',
client: 'fetch',
baseUrl: 'https://vote.optimism.io/api/v1',
mock: false,
override: {
mutator: {
path: './src/utils/custom-fetch.ts',
name: 'customFetch',
},
},
},
hooks: {
afterAllFilesWrite: 'prettier --write',
"op-agora": {
input: "https://vote.optimism.io/api/v1/spec",
output: {
mode: "split",
target: "./src/__generated__/api/agora.ts",
client: "fetch",
baseUrl: "https://vote.optimism.io/api/v1",
mock: false,
override: {
mutator: {
path: "./src/utils/custom-fetch.ts",
name: "customFetch",
},
},
},
hooks: {
afterAllFilesWrite: "prettier --write",
},
});
},
});
50 changes: 50 additions & 0 deletions packages/client/src/actions/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use server";

import {siweConfig} from "@/config/siwe";
import {useAccount} from "wagmi";
import {getSession} from "next-auth/react";

export interface Credentials {
message: string;
signature: string;
// name: string;
// pfp: string;
// redirect: boolean;
}

export async function getNonce() {
try {
const nonce = await siweConfig.getNonce();
return {nonce, message: "Nonce fetched"};
} catch (error) {
return {error, message: "Error getting nonce"};
}
}

export async function getUser() {
const signedInUser = await getSession();

// TODO get user auth roles

return {
...signedInUser,
badgeholder: true,
metrics_admin: true,
council_member: true
}
}

export async function logout() {
try {
await siweConfig.signOut();

return {
message: "User successfully logged out",
};
} catch (error) {
return {
message: "Error logging out user",
error,
};
}
}
16 changes: 16 additions & 0 deletions packages/client/src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,19 @@ button:disabled {
.toaster {
@apply inline-flex min-w-72 items-center gap-4 rounded-xl p-4 shadow;
}

.toaster {
@apply rounded-lg p-2;
}

.toaster-loading {
@apply rounded-lg p-2;
}

.toaster-error {
@apply rounded-lg p-2;
}

.toaste-success {
@apply rounded-lg p-2;
}
11 changes: 11 additions & 0 deletions packages/client/src/app/projects/[uid]/not-found_.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Link from "next/link";

export default function NotFound() {
return (
<main>
<h2>Not Found</h2>
<p>Could not find requested resource</p>
<Link href="/">Return Home</Link>
</main>
);
}
9 changes: 9 additions & 0 deletions packages/client/src/app/projects/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Loader } from "@/components/Loader";

export default function Loading() {
return (
<main className="w-full h-full grid place-items-center">
<Loader />;
</main>
);
}
113 changes: 113 additions & 0 deletions packages/client/src/components/List/Item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
"use client";
import React from "react";
import Image from "next/image";

import { formatLastUpdated } from "@/utils/text";

export interface ListItemProps {
id: string;
title: string;
avatar_image: string;
updated_at: string;
onClick?: () => void;
}

type ColumnValue =
| "project"
| "category"
| "largest-transaction-counts"
| "attestation-counts"
| "last-updated";

interface Column {
value: ColumnValue;
title: string;
}

export const categories: Record<
ProjectCategory,
{ label: string; color: string }
> = {
cefi: {
label: "CeFi",
color: "#e0f2fe",
},
"cross-chain": {
label: "Cross Chain",
color: "#93c5fd",
},
defi: {
label: "DeFi",
color: "#818cf8",
},
governance: {
label: "Governance",
color: "#6ee7b7",
},
nft: {
label: "NFT",
color: "#3b82f6",
},
social: {
label: "Social",
color: "#fef08a",
},
utility: {
label: "Utility",
color: "#fdba74",
},
};

export const ListItem: React.FC<ListItemProps> = ({
id,
title,
avatar_image,
// category,
// transactions_count,
// attestation_counts,
updated_at,
onClick,
...props
}) => {
return (
<li
{...props}
onClick={onClick}
className="cursor-pointer hover:bg-slate-50 hover:shadow-sm flex gap-2 items-center w-full font-light border border-zinc-300 rounded-lg px-4 py-3 transition-all ease-in-out duration-300"
>
<div className="flex gap-2 items-center flex-[4] text-lg font-semibold leading-7">
<div className="aspect-square w-14 h-14 relative bg-cyan-900 rounded-lg">
{avatar_image && (
<Image
src={avatar_image}
alt="project image"
className="aspect-square w-14 h-14"
width={56}
height={56}
/>
)}
</div>
<h4 className="line-clamp-2">{title}</h4>
</div>
<div className={`flex-[2]`}>
{/* <span
style={{
background: categories[category].color,
}}
className="rounded-md text-sm text-zinc-800 p-2 leading-snug"
>
{categories[category].label}
</span> */}
</div>
<div className="flex-[3] leading-snug">
{/* {transactions_count.toLocaleString()} */}
</div>
<div className="flex-[3] leading-snug">
{/* {attestation_counts.toLocaleString()} */}
</div>
<div className="flex-[2] leading-snug capitalize">
{formatLastUpdated(updated_at)}
</div>
</li>
);
};
60 changes: 60 additions & 0 deletions packages/client/src/components/List/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"use client";

import React from "react";

import { ListItem } from "./Item";

export interface ListProps {
items: any[];
columns: { size: number; title: string }[];
onItemClick: (id: string) => void;
}

type ColumnValue =
| "item"
| "category"
| "largest-transaction-counts"
| "attestation-counts"
| "last-updated";

interface Column {
value: ColumnValue;
title: string;
}

export const List: React.FC<ListProps> = ({ items, columns, onItemClick }) => {
return (
<div role="table" className="w-full h-full flex flex-col gap-2">
<ul
role="columnheader"
className="flex w-full gap-2 capitalize border border-zinc-300 shadow-sm rounded-lg px-4 py-2 text-sm text-gray-500 leading-tight"
>
{columns.map((column) => (
<li
style={{
flex: column.size,
}}
key={column.title}
className={`flex-[${column.size}]`}
>
{column.title}
</li>
))}
</ul>
<ul
role="rowgroup"
className="flex w-full flex-col gap-2 flex-1"
>
{items?.map((item) => (
<ListItem
{...item}
key={item.id}
onClick={() => {
onItemClick(item.id);
}}
/>
))}
</ul>
</div>
);
};
2 changes: 1 addition & 1 deletion packages/client/src/components/Project/Attest/Metric.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const ProjectAttestMetric = forwardRef<
ProjectAttestMetricProps
>(({ register, metrics }) => {
return (
<div className="bg-slate-400 collapse collapse-arrow h-full w-full px-8">
<div className="collapse collapse-arrow h-full w-full bg-slate-400 px-8">
<input type="checkbox" />
<div className="collapse-title">
<h3 className="mb-2 flex items-center gap-1">
Expand Down
63 changes: 63 additions & 0 deletions packages/client/src/config/siwe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { getCsrfToken, signIn, signOut, getSession } from "next-auth/react";
import type {
SIWEVerifyMessageArgs,
SIWECreateMessageArgs,
SIWESession,
} from "@web3modal/siwe";
import { createSIWEConfig, formatMessage } from "@web3modal/siwe";
import { sepolia } from "viem/chains";

export const siweConfig = createSIWEConfig({
getMessageParams: async () => ({
domain: typeof window !== "undefined" ? window.location.host : "",
uri: typeof window !== "undefined" ? window.location.origin : "",
chains: [sepolia.id],
statement: "Please sign with your account",
}),
createMessage: ({ address, ...args }: SIWECreateMessageArgs) =>
formatMessage(args, address),
getNonce: async () => {
const nonce = await getCsrfToken();
if (!nonce) {
throw new Error("Failed to get nonce!");
}

return nonce;
},
getSession: async () => {
const session = await getSession()
if (!session) {
throw new Error('Failed to get session!')
}

const { address, chainId } = session as unknown as SIWESession

return { address, chainId }
},
verifyMessage: async ({ message, signature }: SIWEVerifyMessageArgs) => {
try {
const success = await signIn("credentials", {
message,
redirect: false,
signature,
callbackUrl: "/protected",
});

return Boolean(success?.ok);
} catch (error) {
return false;
}
},
signOut: async () => {
try {
await signOut({
redirect: true,
callbackUrl: "/",
});

return true;
} catch (error) {
return false;
}
},
});
Loading

0 comments on commit c9cc6de

Please sign in to comment.