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: Enhance Form Components with Formik Integration and Configurability #31

Merged
merged 9 commits into from
Feb 3, 2025
3 changes: 2 additions & 1 deletion .github/workflows/all-contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ jobs:
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add .
git commit -m "docs: add ${GITHUB_ACTOR} as a contributor"
git push
git push

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@tanstack/react-query": "^5.63.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"formik": "^2.4.6",
"lucide-react": "^0.470.0",
"next": "14.2.23",
"react": "^18",
Expand All @@ -28,7 +29,8 @@
"starknetkit": "^2.6.1",
"tailwind-merge": "^2.6.0",
"tailwindcss-animate": "^1.0.7",
"vaul": "^1.1.2"
"vaul": "^1.1.2",
"yup": "^1.6.1"
},
"devDependencies": {
"@tanstack/eslint-plugin-query": "^5.62.16",
Expand All @@ -42,4 +44,4 @@
"tailwindcss": "^3.4.1",
"typescript": "^5"
}
}
}
3 changes: 2 additions & 1 deletion src/app/(auth)/setup/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";
import SetupPage from "@/module/auth/setup";
import React from "react";

export default function page() {
return <SetupPage />;
}
}
2 changes: 1 addition & 1 deletion src/components/ui/copylink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@ const MiniCopyLink: React.FC<{ text: string }> = ({ text }) => {

MiniCopyLink.displayName = "MiniCopyLink";

export { CopyLink, MiniCopyLink };
export { CopyLink, MiniCopyLink };
33 changes: 33 additions & 0 deletions src/components/ui/form/formwrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Formik, Form } from "formik";
import * as Yup from "yup";

interface FormWrapperProps {
onSubmit: (values: Record<string, any>) => void;
inputs: React.ReactNode; // Accept Input components or other inputs as props
button: React.ReactNode; // Accept a custom button as a prop
initialValues: Record<string, any>; // Configurable initial values
validationSchema: Yup.ObjectSchema<any>; // Configurable validation schema
}

export const FormWrapper: React.FC<FormWrapperProps> = ({
onSubmit,
inputs,
button,
initialValues,
validationSchema,
}) => {
return (
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
>
{() => (
<Form>
{inputs}
{button}
</Form>
)}
</Formik>
);
};
4 changes: 2 additions & 2 deletions src/components/ui/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
type={type}
placeholder={placeholder}
className={cn(
"flex h-9 w-full rounded-md border border-input bg-transparent px-4 py-1 text-blue-950 shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"flex h-9 w-full rounded-md border border-input bg-transparent py-1 px-4 text-blue-950 shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className
)}
ref={ref}
Expand All @@ -20,4 +20,4 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
);
Input.displayName = "Input";

export { Input };
export { Input };
79 changes: 63 additions & 16 deletions src/module/auth/setup.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
"use client";

import { useState } from "react";
import { Camera } from "lucide-react";
import { FormWrapper } from "@/components/ui/form/formwrapper";
import { Input } from "@/components/ui/input";
import * as Yup from "yup";
import { useField } from "formik";
import { Button } from "@/components/ui/button";
import { Camera } from "lucide-react";

export default function SetupPage() {
const [username, setUsername] = useState("");
// Initial form values
const initialValues = {
username: "",
};

// Validation schema
const validationSchema = Yup.object({
username: Yup.string()
.min(6, "Username must be at least 6 characters")
.required("Username is required"),
});

// Form submission handler
const handleSubmit = (values: Record<string, any>) => {
console.log("Submitted values:", values);
};

return (
<div className="flex flex-col w-full pt-[5rem] items-center justify-center">
Expand All @@ -27,19 +42,51 @@ export default function SetupPage() {
<Camera size="16" className="text-blue-950" />
</div>
</div>
<Input
type="text"
placeholder="wager.strk/@username"
value={username}
onChange={(e) => setUsername(e.target.value)}
<FormWrapper
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
inputs={
<div className="flex flex-col space-y-2">
<UsernameField name="username" />
</div>
}
button={
<Button
type="submit"
variant="default"
className="font-medium text-xl tracking-[-2%] h-14 rounded-2xl mt-6"
>
Continue
</Button>
}
/>
<Button
variant="secondary"
className="font-medium text-xl tracking-[-2%] h-14 rounded-2xl"
>
Continue
</Button>
</div>
</div>
);
}

const UsernameField = ({ name }: { name: string }) => {
const [field, meta] = useField(name);

return (
<div className="flex flex-col space-y-2">
<div className="flex items-center bg-[#EFF1F5] rounded-lg px-4 py-6 h-20">
<div className="h-5">
<span className="text-[#B9C0D4] w-24 text-base tracking-tighter">wager.strk/ </span>
<span className="text-[#102A56] w-24 text-base tracking-tighter">@</span>
</div>
<div className="h-5 overflow-hidden">
<Input
{...field}
type="text"
className="flex flex-grow h-18 bg-[#EFF1F5] py-2 text-[#102A56] shadow-sm transition-colors rounded-none text-base tracking-tighter outline-none border-none px-0"
/>
</div>
</div>
{meta.touched && meta.error && (
<span className="text-sm text-red-500">{meta.error}</span>
)}
</div>
);
};
Loading
Loading