Skip to content

Commit

Permalink
Merge pull request #33 from polywrap/style-updates-2
Browse files Browse the repository at this point in the history
Styles for Strategy page
  • Loading branch information
dOrgJelli authored Jan 25, 2024
2 parents afb763b + c3445c3 commit db0292c
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 87 deletions.
27 changes: 21 additions & 6 deletions web/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,37 @@
@tailwind components;
@tailwind utilities;

html {
@apply bg-indigo-300;
}

body {
color: rgb(var(--foreground-rgb));
@apply font-medium bg-gradient-to-br from-indigo-200 to-indigo-300 text-indigo-900;
@apply font-medium text-indigo-900;
}

.checkbox {
@apply rounded border-2 border-indigo-500 w-4 h-4 transition-colors duration-300 cursor-pointer hover:border-indigo-400;
@apply rounded border-2 border-indigo-500 w-5 h-5 transition-colors duration-300 cursor-pointer hover:border-indigo-400;
}

.checkbox.checked {
@apply border-cyan-500 bg-cyan-500/50 text-white hover:border-cyan-400;
@apply border-indigo-500 bg-indigo-500/50 text-white hover:border-indigo-400;
}

.checkmark {
@apply w-full h-full bg-no-repeat;
background-image: url("../public/checkmark.svg");
background-size: 70%;
background-position: 56% 58%;
background-size: 65%;
background-position: 52% 57%;
}

.text-subdued {
@apply text-indigo-900/60;
}

th {
@apply px-4 pt-4 pb-2 text-indigo-900/50 font-semibold text-xs leading-none uppercase;
}

td {
@apply p-4;
}
11 changes: 5 additions & 6 deletions web/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Plus_Jakarta_Sans } from "next/font/google";

import "./globals.css";
import WalletProvider from "./WalletProvider";
import Main from "./main";
import { Logo } from "@/components/Logo";

const sans = Plus_Jakarta_Sans({
Expand All @@ -17,7 +18,7 @@ export const metadata: Metadata = {

function Header() {
return (
<div className='flex w-full justify-between text-sm p-6 pb-2'>
<div className='flex w-full justify-between text-sm px-6 py-3 bg-indigo-300/50 border-b-2 border-indigo-400/20'>
<a href='/' className='flex hover:opacity-80'>
<Logo size={160} />
</a>
Expand Down Expand Up @@ -53,13 +54,11 @@ export default function RootLayout({
<html lang='en'>
<body className={sans.className}>
<WalletProvider>
<main className='flex h-screen min-h-screen flex-col items-center'>
<Main>
<Header />
<div className='flex flex-col w-full flex-grow overflow-y-auto'>
{children}
</div>
{children}
<Footer />
</main>
</Main>
</WalletProvider>
</body>
</html>
Expand Down
10 changes: 10 additions & 0 deletions web/app/lib/utils/pluralize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
interface PluralizeProps {
strings: string[];
count: number;
}

// If count is greater than 1,
// the second string will be used,
// otherwise the first will be used
export const pluralize = (strings: string[], count: number) =>
strings[count && count > 1 ? 1 : 0];
22 changes: 22 additions & 0 deletions web/app/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"use client";

import { usePathname } from "next/navigation";
import clsx from "clsx";

export default function Main({ children }: { children: React.ReactNode }) {
const pathname = usePathname();

return (
<main
className={clsx(
"flex h-screen min-h-screen flex-col items-center",
pathname === "/"
? "bg-gradient-to-br from-indigo-200 to-indigo-300"
: "bg-gradient-to-b from-indigo-300 via-indigo-50 to-white"
)}>
<div className='flex flex-col w-full flex-grow overflow-y-auto'>
{children}
</div>
</main>
);
}
2 changes: 1 addition & 1 deletion web/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const Button = ({
const [showTooltip, setShowTooltip] = useState<boolean>(false);
const hierarchyClasses = {
primary: clsx(
"bg-button border-cyan-300 bg-gradient-to-b from-cyan-300 via-cyan-600 to-cyan-800 bg-bottom text-white",
"border-indigo-100 bg-indigo-900 text-white shadow-button transform active:translate-y-1 active:bg-indigo-800/90 hover:bg-indigo-600 transition-all duration-100 ease-in-out active:shadow-button-0 focus-visible:ring-1 focus-visible:ring-white focus-visible:outline-0",
{
"hover:bg-top": !disabled,
}
Expand Down
56 changes: 56 additions & 0 deletions web/components/Icons.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import colors from "tailwindcss/colors";

export interface IconProps {
size?: number;
className?: string;
Expand Down Expand Up @@ -60,3 +62,57 @@ export const SparkleIcon = ({ size = 32, className }: IconProps) => {
</svg>
);
};

export interface ScoreIconProps extends IconProps {
rank: number;
}

export const ScoreIcon = ({ size = 20, rank, className }: ScoreIconProps) => {
const ranking = rank > 0.74 ? "high" : rank < 0.53 ? "low" : "med";
const fills = {
high: {
fill: colors.green[500],
opacities: [1, 1, 1],
},
med: {
fill: colors.amber[500],
opacities: [1, 1, 0.3],
},
low: {
fill: colors.red[500],
opacities: [1, 0.3, 0.3],
},
};

return (
<svg
width={size}
height={(size * 2) / 3}
viewBox='0 0 12 8'
className={className}
fill='none'
xmlns='http://www.w3.org/2000/svg'>
<rect
width='3'
height='4'
transform='matrix(-1 0 0 1 3.5 4)'
fill={fills[ranking].fill}
fillOpacity={fills[ranking].opacities[0]}
/>
<rect
width='3'
height='6'
transform='matrix(-1 0 0 1 7.5 2)'
fill={fills[ranking].fill}
fillOpacity={fills[ranking].opacities[1]}
/>
<rect
width='3'
height='8'
transform='matrix(-1 0 0 1 11.5 0)'
fill={fills[ranking].fill}
fillOpacity={fills[ranking].opacities[2]}
/>
</svg>
);
};
28 changes: 11 additions & 17 deletions web/components/Score.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import HighScoreIcon from "@/public/high-score-icon.svg";
import CopyToClipboardIcon from "@/public/copy-to-clipboard.svg"
import Image from "next/image";
import { Info } from "@phosphor-icons/react/dist/ssr";
import { ScoreIcon } from "./Icons";

export default function Score({ rank }: { rank: number }) {
// TODO: Attach medium and low icons
const Icon = rank > 0.6 ? HighScoreIcon : null;
if (Icon) {
return (
<div className="flex flex-wrap gap-2 items-center justify-center">
<div>
<Image alt="score" priority src={Icon} />
</div>
return (
<div className='flex flex-wrap gap-2 items-center justify-between'>
<div className='flex space-x-2 items-center'>
<ScoreIcon rank={rank} />
<div>{(rank * 10).toFixed(1)}</div>
<div>
<Image className="hover:cursor-pointer" alt="copy-clipboard" src={CopyToClipboardIcon} />
</div>
</div>
);
}
return null;
<div>
<Info size={20} className='text-indigo-300 hover:text-indigo-500' />
</div>
</div>
);
}
48 changes: 28 additions & 20 deletions web/components/Strategy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { StrategyTable, StrategyWithProjects } from "./StrategyTable";
import TextField from "./TextField";
import { useConnectWallet } from "@web3-onboard/react";
import Dropdown from "./Dropdown";
import { pluralize } from "@/app/lib/utils/pluralize";

function Information(props: {
title: string;
Expand All @@ -15,10 +16,10 @@ function Information(props: {
disabled?: boolean;
}) {
return (
<div className="flex flex-wrap justify-between">
<div className="flex flex-col">
<div>{props.title}</div>
<div className="text-[12px] text-slate-500">{props.subtitle}</div>
<div className='flex flex-wrap justify-between'>
<div className='flex flex-col'>
<div className='text-lg font-semibold'>{props.title}</div>
<div className='text-xs text-subdued'>{props.subtitle}</div>
</div>
<Button disabled={props.disabled} onClick={props.onClick}>
{props.action}
Expand Down Expand Up @@ -51,10 +52,10 @@ export default function Strategy(props: {
}

return (
<div className="flex items-center justify-center py-12">
<div className="flex flex-col gap-4 justify-center w-3/5">
<div className='flex justify-center py-10 flex-grow flex-column'>
<div className='flex flex-col gap-4 mx-auto max-w-wrapper space-y-4'>
<TextField
label="Results for"
label='Results for'
value={currentPromp}
onChange={(e) => setCurrentPrompt(e.target.value)}
/>
Expand All @@ -64,36 +65,43 @@ export default function Strategy(props: {
and have listed the top 10 most impactful projects below. I&apos;ve
also allotted a weighting for each to appropriately fund each project.
</p>
<div className="flex flex-col gap-4 border-zinc-700 rounded-lg border-2 p-8">
<div className='flex flex-col gap-4 bg-indigo-50 shadow-xl shadow-primary-shadow/10 rounded-3xl border-2 border-indigo-200 p-4'>
{!!wallet && (
<TextField
label="Total Funding Amount"
label='Total Funding Amount'
rightAdornment={
<Dropdown items={["USDC"]} field={{ value: "USDC" }} />
}
value={amount}
onChange={(e) => setAmount(+e.target.value)}
/>
)}
<div className="bg-gray-800 text-gray-300 rounded-lg shadow-md">
<StrategyTable
strategy={currentStrategy}
modifyStrategy={setCurrentStrategy}
/>
</div>
<StrategyTable
strategy={currentStrategy}
modifyStrategy={setCurrentStrategy}
/>
</div>
{!wallet ? (
<Information
title={`${selectedStrategiesLength} ${props.prompt} projects`}
subtitle="Connect your wallet to fund these projects"
action="Connect →"
title={`${selectedStrategiesLength} ${props.prompt} ${pluralize(
["project", "projects"],
selectedStrategiesLength
)}`}
subtitle={`Connect your wallet to fund ${pluralize(
["this project", "these projects"],
selectedStrategiesLength
)}`}
action='Connect →'
onClick={() => connect()}
/>
) : (
<Information
title={`Funding ${currentStrategy.length} projects`}
title={`Funding ${currentStrategy.length} ${pluralize(
["project", "projects"],
selectedStrategiesLength
)}`}
subtitle="Please provide an amount you'd like to fund"
action="Next →"
action='Next →'
onClick={() => {}}
disabled={selectedStrategiesLength === 0 || amount === 0}
/>
Expand Down
44 changes: 22 additions & 22 deletions web/components/StrategyTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ export interface StrategyTableProps {

export function StrategyTable(props: StrategyTableProps) {
return (
<table className="table-fixed">
<table className='table-fixed text-sm bg-white overflow-hidden rounded-xl ring-2 ring-indigo-100'>
<thead>
<tr>
<th className="px-4">
<th className='pr-0'>
<TextField
type="checkbox"
type='checkbox'
checked={props.strategy.every((s) => s.selected)}
onChange={(e) => {
props.modifyStrategy(
Expand All @@ -35,21 +35,19 @@ export function StrategyTable(props: StrategyTableProps) {
}}
/>
</th>
<th className="text-left">PROJECT</th>
<th>
<div className="pl-2 w-auto">WEIGHTING</div>
</th>
<th className="w-1/5">
<div className="flex w-1/5 pl-12">SMART RANKING</div>
</th>
<th className='text-left'>PROJECT</th>
<th className='text-left'>WEIGHTING</th>
<th className='text-left w-2/12 whitespace-nowrap'>SMART RANKING</th>
</tr>
</thead>
<tbody className="bg-gray-900 w-full">
<tbody className='w-full'>
{props.strategy.map((entry, index) => (
<tr key={index} className="w-full">
<td className="px-6 pl-4">
<tr
key={index}
className='w-full border-indigo-100/80 border-t-2 bg-indigo-50/50 odd:bg-indigo-50'>
<td className='pr-0'>
<TextField
type="checkbox"
type='checkbox'
checked={entry.selected}
onChange={(e) => {
const currentStrategy = [...props.strategy];
Expand All @@ -58,26 +56,28 @@ export function StrategyTable(props: StrategyTableProps) {
}}
/>
</td>
<td className="w-7/12">
<div className="flex flex-col pt-2 pb-4 mr-6 w-full">
<td className='min-w-6/12'>
<div className='space-y-px w-full'>
<div>{entry.project.title}</div>
<div className="text-[10px] text-slate-500 line-clamp-2">
<div className='text-[10px] text-subdued line-clamp-2 leading-tight'>
{entry.project.description}
{entry.project.description}
{entry.project.description}
</div>
</div>
</td>
<td className="pl-2 w-auto">
<div className="w-full justify-center">
<td className='w-2/12'>
<div className='w-full justify-center'>
<TextField
readOnly
className="h-[20px] p-2.5"
className='!pl-4 !pr-6 !py-1 !border-indigo-100 !shadow-none bg-white'
rightAdornment={"%"}
value={!entry.weight ? "0" : (entry.weight * 100).toFixed(2)}
/>
</div>
</td>
<td className="w-1/5">
<div className="w-full">
<td>
<div className='w-full'>
<Score rank={entry.impact ?? 0} />
</div>
</td>
Expand Down
Loading

0 comments on commit db0292c

Please sign in to comment.