Informational and text templates
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
"use client";
|
||||
|
||||
import { useMediaQuery } from "../../hooks/useMediaQuery";
|
||||
import HeaderLockup from "../../components/type/HeaderLockup";
|
||||
import NumberedList from "../../components/type/NumberedList";
|
||||
|
||||
/**
|
||||
* Informational page for the create flow
|
||||
*
|
||||
* Displays information about the create flow process using HeaderLockup and NumberedList components.
|
||||
* Responsive sizing: uses L/M for HeaderLockup and M/S for NumberedList based on 640px breakpoint.
|
||||
*/
|
||||
export default function InformationalPage() {
|
||||
const isMdOrLarger = useMediaQuery("(min-width: 640px)");
|
||||
|
||||
const items = [
|
||||
{
|
||||
title: "Tell us about your organization",
|
||||
description:
|
||||
"Start by providing your group's name, description, and profile image.",
|
||||
},
|
||||
{
|
||||
title: "Define your group's CommunityRule.",
|
||||
description:
|
||||
"Outline decision-making processes, conflict resolution methods, and membership practices. Get recommendations.",
|
||||
},
|
||||
{
|
||||
title: "Share and evolve over time",
|
||||
description:
|
||||
"Review and refine your community framework before putting it into action and adapting it over time.",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-col items-center px-[var(--spacing-measures-spacing-500,20px)] md:px-[64px]">
|
||||
<div className="flex flex-col gap-[48px] items-center w-full max-w-[640px]">
|
||||
{/* HeaderLockup: Left justification, L size at 640px+, M size below 640px */}
|
||||
<HeaderLockup
|
||||
title="How CommunityRule helps groups like yours"
|
||||
description="This flow will give you recommendations to improve your community and help you put together a proposal for your group to consider. Alternatively, there is a workshop that your group can use to go through the process it together."
|
||||
justification="left"
|
||||
size={isMdOrLarger ? "L" : "M"}
|
||||
/>
|
||||
|
||||
{/* NumberedList: M size at 640px+, S size below 640px */}
|
||||
<NumberedList items={items} size={isMdOrLarger ? "M" : "S"} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+85
-18
@@ -1,10 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { CreateFlowProvider } from "./context/CreateFlowContext";
|
||||
import CreateFlowTopNav from "../components/utility/CreateFlowTopNav";
|
||||
import CreateFlowFooter from "../components/utility/CreateFlowFooter";
|
||||
import Button from "../components/buttons/Button";
|
||||
import type { CreateFlowStep } from "./types";
|
||||
|
||||
/**
|
||||
* Layout for the Create Rule Flow
|
||||
@@ -13,6 +15,88 @@ import Button from "../components/buttons/Button";
|
||||
* This layout wraps all create flow pages and provides the CreateFlowContext.
|
||||
* Includes the create flow-specific TopNav and Footer components.
|
||||
*/
|
||||
function CreateFlowLayoutContent({ children }: { children: ReactNode }) {
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
|
||||
// Extract current step from pathname
|
||||
const currentStep = pathname?.split("/").pop() as CreateFlowStep | undefined;
|
||||
|
||||
// Define step order
|
||||
const stepOrder: CreateFlowStep[] = [
|
||||
"informational",
|
||||
"text",
|
||||
"select",
|
||||
"upload",
|
||||
"review",
|
||||
"compact-cards",
|
||||
"expanded-cards",
|
||||
"right-rail",
|
||||
"final-review",
|
||||
"completed",
|
||||
];
|
||||
|
||||
// Get next step
|
||||
const getNextStep = (): CreateFlowStep | null => {
|
||||
if (!currentStep) return null;
|
||||
const currentIndex = stepOrder.indexOf(currentStep);
|
||||
if (currentIndex === -1 || currentIndex === stepOrder.length - 1) {
|
||||
return null;
|
||||
}
|
||||
return stepOrder[currentIndex + 1];
|
||||
};
|
||||
|
||||
// Get previous step
|
||||
const getPreviousStep = (): CreateFlowStep | null => {
|
||||
if (!currentStep) return null;
|
||||
const currentIndex = stepOrder.indexOf(currentStep);
|
||||
if (currentIndex === -1 || currentIndex === 0) {
|
||||
return null;
|
||||
}
|
||||
return stepOrder[currentIndex - 1];
|
||||
};
|
||||
|
||||
const nextStep = getNextStep();
|
||||
const previousStep = getPreviousStep();
|
||||
|
||||
const handleNext = () => {
|
||||
if (nextStep) {
|
||||
router.push(`/create/${nextStep}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
if (previousStep) {
|
||||
router.push(`/create/${previousStep}`);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-black flex flex-col">
|
||||
<CreateFlowTopNav />
|
||||
<main className="flex-1 flex items-center justify-center overflow-auto">
|
||||
{children}
|
||||
</main>
|
||||
<CreateFlowFooter
|
||||
secondButton={
|
||||
nextStep ? (
|
||||
<Button
|
||||
buttonType="filled"
|
||||
palette="default"
|
||||
size="xsmall"
|
||||
className="md:!text-[14px] md:!leading-[16px] !text-[12px] !leading-[14px] !px-[var(--spacing-measures-spacing-200,8px)] md:!px-[var(--spacing-measures-spacing-250,10px)] !py-[var(--spacing-measures-spacing-200,8px)] md:!py-[var(--spacing-measures-spacing-250,10px)]"
|
||||
onClick={handleNext}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
) : null
|
||||
}
|
||||
onBackClick={previousStep ? handleBack : undefined}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function CreateFlowLayout({
|
||||
children,
|
||||
}: {
|
||||
@@ -20,24 +104,7 @@ export default function CreateFlowLayout({
|
||||
}) {
|
||||
return (
|
||||
<CreateFlowProvider>
|
||||
<div className="min-h-screen bg-black flex flex-col">
|
||||
<CreateFlowTopNav />
|
||||
<main className="flex-1 overflow-auto">
|
||||
{children}
|
||||
</main>
|
||||
<CreateFlowFooter
|
||||
secondButton={
|
||||
<Button
|
||||
buttonType="filled"
|
||||
palette="default"
|
||||
size="xsmall"
|
||||
className="md:!text-[14px] md:!leading-[16px] !text-[12px] !leading-[14px] !px-[var(--spacing-measures-spacing-200,8px)] md:!px-[var(--spacing-measures-spacing-250,10px)] !py-[var(--spacing-measures-spacing-200,8px)] md:!py-[var(--spacing-measures-spacing-250,10px)]"
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<CreateFlowLayoutContent>{children}</CreateFlowLayoutContent>
|
||||
</CreateFlowProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useMediaQuery } from "../../hooks/useMediaQuery";
|
||||
import HeaderLockup from "../../components/type/HeaderLockup";
|
||||
import TextInput from "../../components/controls/TextInput";
|
||||
|
||||
/**
|
||||
* Text page for the create flow
|
||||
*
|
||||
* Displays a text input field for user input using HeaderLockup and TextInput components.
|
||||
* Responsive sizing: uses L/M for HeaderLockup and medium/small for TextInput based on 640px breakpoint.
|
||||
*/
|
||||
export default function TextPage() {
|
||||
const isMdOrLarger = useMediaQuery("(min-width: 640px)");
|
||||
const [value, setValue] = useState("");
|
||||
|
||||
const maxLength = 48;
|
||||
const characterCount = value.length;
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-col items-center px-[var(--spacing-measures-spacing-500,20px)] md:px-[64px]">
|
||||
<div className="flex flex-col gap-[18px] items-start w-full max-w-[640px]">
|
||||
{/* HeaderLockup: Left justification, L size at 640px+, M size below 640px */}
|
||||
<HeaderLockup
|
||||
title="What is your community called?"
|
||||
description="This will be the name of your community"
|
||||
justification="left"
|
||||
size={isMdOrLarger ? "L" : "M"}
|
||||
/>
|
||||
|
||||
{/* TextInput: medium size at 640px+, small size below 640px */}
|
||||
<div className="w-full">
|
||||
<TextInput
|
||||
placeholder="Enter your community name"
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
inputSize={isMdOrLarger ? "medium" : "small"}
|
||||
formHeader={false}
|
||||
textHint={`${characterCount}/${maxLength}`}
|
||||
maxLength={maxLength}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user