mirror of
https://github.com/xHyroM/roles-bot.git
synced 2024-11-10 03:08:06 +01:00
feat: multi step form
This commit is contained in:
parent
0cdb41abb7
commit
a865aa5532
3 changed files with 158 additions and 1 deletions
128
apps/website/src/components/preact/MultiStepForm.tsx
Normal file
128
apps/website/src/components/preact/MultiStepForm.tsx
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
import { useState, useEffect } from "preact/hooks";
|
||||||
|
|
||||||
|
const steps = [
|
||||||
|
{ id: 1, name: "Select Channel" },
|
||||||
|
{ id: 2, name: "Add Buttons/Dropdowns" },
|
||||||
|
{ id: 3, name: "Set Message Content" },
|
||||||
|
{ id: 4, name: "Send" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const MultiStepForm = ({ guildId }) => {
|
||||||
|
const [currentStep, setCurrentStep] = useState(1);
|
||||||
|
const [channels, setChannels] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(`/api/guild/${guildId}/channels`)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => setChannels(data));
|
||||||
|
}, [guildId]);
|
||||||
|
|
||||||
|
const nextStep = () => {
|
||||||
|
setCurrentStep((prevStep) => Math.min(prevStep + 1, steps.length));
|
||||||
|
};
|
||||||
|
|
||||||
|
const prevStep = () => {
|
||||||
|
setCurrentStep((prevStep) => Math.max(prevStep - 1, 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mx-auto w-full max-w-lg rounded-lg bg-gray-800 p-6 text-white shadow-lg">
|
||||||
|
<div className="relative pt-1">
|
||||||
|
<div className="mb-2 flex items-center justify-between">
|
||||||
|
<div className="text-right">
|
||||||
|
<span className="inline-block text-xs font-semibold text-green-400">
|
||||||
|
Step {currentStep} of {steps.length}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mb-4 flex h-2 overflow-hidden rounded bg-gray-700 text-xs">
|
||||||
|
<div
|
||||||
|
style={{ width: `${(currentStep / steps.length) * 100}%` }}
|
||||||
|
className="flex flex-col justify-center whitespace-nowrap bg-green-500 text-center text-white shadow-none"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{currentStep === 1 && (
|
||||||
|
<div>
|
||||||
|
<label className="mb-2 block">Select Channel:</label>
|
||||||
|
<select className="mb-4 w-full rounded border border-gray-600 bg-gray-700 p-2">
|
||||||
|
{channels.map((channel) => (
|
||||||
|
<option key={channel.id} value={channel.id}>
|
||||||
|
{channel.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<button
|
||||||
|
onClick={nextStep}
|
||||||
|
className="mt-4 w-full rounded bg-white px-4 py-2 text-gray-800 hover:bg-gray-200"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{currentStep === 2 && (
|
||||||
|
<div>
|
||||||
|
<label className="mb-2 block">Add Buttons/Dropdowns:</label>
|
||||||
|
{/* Add buttons or dropdowns here */}
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<button
|
||||||
|
onClick={prevStep}
|
||||||
|
className="mt-4 w-full rounded bg-gray-600 px-4 py-2 text-white hover:bg-gray-700"
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={nextStep}
|
||||||
|
className="mt-4 w-full rounded bg-white px-4 py-2 text-gray-800 hover:bg-gray-200"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{currentStep === 3 && (
|
||||||
|
<div>
|
||||||
|
<label className="mb-2 block">Set Message Content:</label>
|
||||||
|
{/* Set message content, embed, etc. here */}
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<button
|
||||||
|
onClick={prevStep}
|
||||||
|
className="mt-4 w-full rounded bg-gray-600 px-4 py-2 text-white hover:bg-gray-700"
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={nextStep}
|
||||||
|
className="mt-4 w-full rounded bg-white px-4 py-2 text-gray-800 hover:bg-gray-200"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{currentStep === 4 && (
|
||||||
|
<div>
|
||||||
|
<label className="mb-2 block">Review and Send:</label>
|
||||||
|
{/* Send message here */}
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<button
|
||||||
|
onClick={prevStep}
|
||||||
|
className="mt-4 w-full rounded bg-gray-600 px-4 py-2 text-white hover:bg-gray-700"
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</button>
|
||||||
|
<button className="mt-4 w-full rounded bg-white px-4 py-2 text-gray-800 hover:bg-gray-200">
|
||||||
|
Send
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MultiStepForm;
|
14
apps/website/src/pages/api/guild/[id]/channels.ts
Normal file
14
apps/website/src/pages/api/guild/[id]/channels.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import type { APIRoute } from "astro";
|
||||||
|
import { filterUserGuilds, getUserGuilds } from "~/lib/guilds";
|
||||||
|
|
||||||
|
export const GET: APIRoute = async ({ locals }) => {
|
||||||
|
const user = locals.user;
|
||||||
|
if (!user) {
|
||||||
|
return new Response(null, {
|
||||||
|
status: 401,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(user);
|
||||||
|
return Response.json([]);
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
import GuildInfo from "~/components/dashboard/GuildInfo.astro";
|
import GuildInfo from "~/components/dashboard/GuildInfo.astro";
|
||||||
import UserInfo from "~/components/dashboard/UserInfo.astro";
|
import UserInfo from "~/components/dashboard/UserInfo.astro";
|
||||||
|
import MultiStepForm from "~/components/preact/MultiStepForm";
|
||||||
import Layout from "~/layouts/Layout.astro";
|
import Layout from "~/layouts/Layout.astro";
|
||||||
import { getGuild } from "~/lib/guilds";
|
import { getGuild } from "~/lib/guilds";
|
||||||
import { isUserEligible } from "~/lib/user";
|
import { isUserEligible } from "~/lib/user";
|
||||||
|
@ -32,5 +33,19 @@ if (!eligible) {
|
||||||
<GuildInfo id={guild.id} name={guild.name} icon={guild.icon} />
|
<GuildInfo id={guild.id} name={guild.name} icon={guild.icon} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
You can manage guild {guild.name} with id {guild.id}
|
<div class="mx-auto mt-8 w-full max-w-lg">
|
||||||
|
<MultiStepForm guildId={guild.id} client:load />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.step {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.step.active {
|
||||||
|
background-color: #4caf50;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
Loading…
Reference in a new issue