Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add auth pages #5

Merged
merged 4 commits into from
Oct 22, 2024
Merged
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
Binary file added .DS_Store
Binary file not shown.
Binary file added packages/.DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions packages/frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ dist-ssr
!.vscode/extensions.json
.idea
.DS_Store
**/.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

18 changes: 18 additions & 0 deletions packages/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
"preview": "vite preview"
},
"dependencies": {
"clsx": "^2.1.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.3.0",
"react-router-dom": "^6.27.0",
"zustand": "^5.0.0"
},
Expand Down
26 changes: 26 additions & 0 deletions packages/frontend/src/lib/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import clsx from "clsx";

type ButtonProps = {
isDisabled?: boolean;
className?: string;
};

function Button({ isDisabled, className }: ButtonProps) {
return (
<button
type="submit"
disabled={isDisabled}
className={clsx(
"rounded-[8px] bg-yellow-dark-4 py-[1rem] text-center text-yellow-dark-11 shadow-md transition duration-100 ease-in-out hover:bg-yellow-dark-5 ",
{
"cursor-not-allowed opacity-60": isDisabled,
},
className
)}
>
Submit
</button>
);
}

export default Button;
149 changes: 149 additions & 0 deletions packages/frontend/src/lib/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import clsx from "clsx";
import React, { useEffect, useState } from "react";

interface InputProps {
type?: "text" | "email" | "textarea" | "password";
value: string;
onChange?: (value: string) => void;
label: string;
readOnly?: boolean;
name: string;
isRequired: boolean;
minLength?: number;
maxLength?: number;
bottomText?: string;
pattern?: string;
className?: string;
disabled?: boolean;
[key: string]: any;
}

interface IsRequiredComponentProps {
isRequired: boolean;
}

const Input: React.FC<InputProps> = ({
type = "text",
value: propValue = "",
onChange,
label = "Name",
readOnly,
isRequired,
bottomText,
pattern,
minLength,
maxLength,
error,
disabled,
className,
name,
...props
}) => {
const [inputValue, setInputValue] = useState<string>(propValue);
const [showPassword, setShowPassword] = useState<boolean>(false);

useEffect(() => {
setInputValue(propValue);
}, [propValue]);

const handleChange = (
e:
| React.ChangeEvent<HTMLInputElement>
| React.ChangeEvent<HTMLTextAreaElement>
) => {
const newValue = e.target.value;
setInputValue(newValue);
if (onChange) {
onChange(newValue);
}
};

const togglePasswordVisibility = () => {
setShowPassword((prev) => !prev);
};

if (type === "textarea") {
return (
<div>
<label
className="my-[.6rem] inline-block text-[1.3rem] sm:text-[1.4rem] xl:my-[1rem]"
htmlFor={`input-${name}`}
>
{label}
<IsRequiredField isRequired={isRequired} />
</label>
<textarea
id={`input-${name}`}
rows={10}
placeholder="Describe your issue..."
value={inputValue}
minLength={minLength}
maxLength={maxLength}
onChange={handleChange}
{...props}
className={clsx(
"focus:border-ui-medium-blue w-full rounded-[6px] border border-ui-mid-white bg-gray-dark-1 px-[1.1rem] py-[.7rem] text-[1.3rem] outline-none placeholder:text-[1.5rem] md:text-[1.6rem]",
{
"cursor-not-allowed": disabled,
},
className
)}
/>
</div>
);
}

return (
<div className="relative">
<label
className="my-[.6rem] inline-block text-[1rem] xl:my-[1rem] text-white"
htmlFor={`input-${name}`}
>
{label}
<IsRequiredField isRequired={isRequired} />
</label>
<div className="relative">
<input
className={clsx(
"focus:border-ui-medium-blue w-full rounded-[6px] border border-ui-mid-white bg-black px-[1.1rem] py-[.4rem] text-[1rem] outline-none focus:border md:text-[1.2rem]",
{
"cursor-not-allowed": readOnly || disabled,
},
className
)}
type={showPassword && type === "password" ? "text" : type}
required
id={`input-${name}`}
readOnly={readOnly}
name={name}
minLength={minLength}
maxLength={maxLength}
value={inputValue}
pattern={pattern}
disabled={disabled}
onChange={handleChange}
{...props}
/>

{type === "password" && (
<span
className="absolute right-[1.1rem] top-[50%] translate-y-[-50%] cursor-pointer"
onClick={togglePasswordVisibility}
>
{showPassword ? "🙈" : "👁️"}{" "}
</span>
)}
</div>
</div>
);
};

function IsRequiredField({ isRequired }: IsRequiredComponentProps) {
return (
<span className={clsx({ "text-yellow-dark-9": isRequired })}>
{isRequired ? "*" : "(Optional)"}
</span>
);
}

export default Input;
147 changes: 147 additions & 0 deletions packages/frontend/src/lib/icons/MetamaskIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import clsx from "clsx";
import React from "react";

interface MetaMaskIconProps {
size?: number;
className?: string;
}

const MetaMaskIcon: React.FC<MetaMaskIconProps> = ({
size = "1em",
className,
}) => {
return (
<svg
width={`${size}`}
height={`${size}`}
viewBox="0 0 256 240"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
preserveAspectRatio="xMidYMid"
className={clsx(className)}
>
<title>MetaMask</title>
<g>
<polygon
fill="#E17726"
points="250.066018 0 140.218553 81.2793133 160.645643 33.3787726"
></polygon>
<polygon
fill="#E27625"
points="6.19062016 0.0955267053 95.3715526 33.38465 114.767923 81.9132784"
></polygon>
<polygon
fill="#E27625"
points="205.859986 172.858026 254.410647 173.782023 237.442988 231.424252 178.200429 215.112736"
></polygon>
<polygon
fill="#E27625"
points="50.1391619 172.857971 77.6964289 215.11288 18.5530579 231.425317 1.68846828 173.782036"
></polygon>
<polygon
fill="#E27625"
points="112.130724 69.5516472 114.115388 133.635085 54.744344 130.933905 71.6319541 105.456448 71.8456974 105.210668"
></polygon>
<polygon
fill="#E27625"
points="143.254237 68.8369186 184.153999 105.213392 184.365514 105.45719 201.253537 130.934656 141.89632 133.635226"
></polygon>
<polygon
fill="#E27625"
points="79.4347776 173.043957 111.853145 198.302774 74.1951401 216.484384"
></polygon>
<polygon
fill="#E27625"
points="176.57078 173.040009 181.701672 216.484523 144.149363 198.301203"
></polygon>
<polygon
fill="#D5BFB2"
points="144.977922 195.921642 183.084879 214.373531 147.637779 231.220354 148.005818 220.085704"
></polygon>
<polygon
fill="#D5BFB2"
points="111.01133 195.929982 108.102093 219.90359 108.340838 231.207237 72.8105145 214.373665"
></polygon>
<polygon
fill="#233447"
points="100.007166 141.998856 109.965172 162.926822 76.0615945 152.995277"
></polygon>
<polygon
fill="#233447"
points="155.991579 142.000941 180.049716 152.994594 146.03608 162.923638"
></polygon>
<polygon
fill="#CC6228"
points="82.0263962 172.830401 76.5459821 217.870023 47.1731221 173.814952"
></polygon>
<polygon
fill="#CC6228"
points="173.976111 172.8305 208.830462 173.815081 179.347016 217.871514"
></polygon>
<polygon
fill="#CC6228"
points="202.112267 128.387342 176.746779 154.238424 157.190334 145.301352 147.82685 164.985265 141.688645 131.136429"
></polygon>
<polygon
fill="#CC6228"
points="53.8753865 128.386879 114.309585 131.136429 108.17138 164.985265 98.8061425 145.303856 79.3525107 154.238823"
></polygon>
<polygon
fill="#E27525"
points="52.165606 123.082486 80.8639084 152.203386 81.8584812 180.952278"
></polygon>
<polygon
fill="#E27525"
points="203.863346 123.029784 174.117491 181.003017 175.237428 152.202737"
></polygon>
<polygon
fill="#E27525"
points="112.906762 124.855691 114.061658 132.125682 116.915771 150.236518 115.080954 205.861884 106.405804 161.177486 106.402953 160.71542"
></polygon>
<polygon
fill="#E27525"
points="143.077997 124.755417 149.599051 160.715451 149.596194 161.177486 140.899333 205.973714 140.55515 194.76913 139.198167 149.907127"
></polygon>
<polygon
fill="#F5841F"
points="177.788479 151.045975 176.81718 176.023897 146.543342 199.61119 140.4233 195.28712 147.283427 159.951634"
></polygon>
<polygon
fill="#F5841F"
points="78.3167053 151.046455 108.716464 159.952427 115.576437 195.28712 109.456385 199.611197 79.1807344 176.021881"
></polygon>
<polygon
fill="#C0AC9D"
points="67.0180978 208.857597 105.750143 227.209502 105.586194 219.372868 108.826835 216.528328 147.160694 216.528328 150.518758 219.363342 150.271375 227.194477 188.757733 208.903978 170.030292 224.379509 147.384611 239.933315 108.516484 239.933315 85.8855503 224.315941"
></polygon>
<polygon
fill="#161616"
points="142.203502 193.479367 147.679764 197.347701 150.888964 222.952494 146.244706 219.030957 109.769299 219.030957 105.213447 223.031398 108.317268 197.349663 113.795429 193.479367"
></polygon>
<polygon
fill="#763E1A"
points="242.814251 2.24978946 256 41.8072765 247.765337 81.803692 253.629038 86.3274221 245.694407 92.3812097 251.657525 96.9865879 243.761206 104.178247 248.609106 107.688972 235.743366 122.714803 182.973386 107.350364 182.516079 107.105244 144.488982 75.0267414"
></polygon>
<polygon
fill="#763E1A"
points="13.1860054 2.24978557 111.51151 75.0267402 73.4844118 107.105244 73.0271023 107.350365 20.2567388 122.714804 7.39121291 107.688927 12.2352706 104.180751 4.34251001 96.9865923 10.2945566 92.3862179 2.24133703 86.315099 8.32629691 81.7886671 0 41.8087534"
></polygon>
<polygon
fill="#F5841F"
points="180.391638 103.990363 236.304873 120.269177 254.470245 176.254719 206.546445 176.25462 173.525532 176.671282 197.539657 129.863284"
></polygon>
<polygon
fill="#F5841F"
points="75.6080363 103.990376 58.4568191 129.863284 82.4741865 176.671282 49.4693913 176.254719 1.63053271 176.254719 19.6938968 120.269548"
></polygon>
<polygon
fill="#F5841F"
points="163.383898 33.1117385 147.744691 75.3505047 144.425852 132.411352 143.155934 150.295986 143.055195 195.983514 112.943788 195.983514 112.846176 150.381702 111.572114 132.395585 108.251786 75.3505047 92.6150854 33.1117385"
></polygon>
</g>
</svg>
);
};

export default MetaMaskIcon;
Loading