Skip to content

Instantly share code, notes, and snippets.

@ruxiang05
Created July 20, 2025 14:43
Show Gist options
  • Select an option

  • Save ruxiang05/38f2dd6998120e8eac491b3fa1a401ea to your computer and use it in GitHub Desktop.

Select an option

Save ruxiang05/38f2dd6998120e8eac491b3fa1a401ea to your computer and use it in GitHub Desktop.
Gigs Provisioning
import { useReducer } from "react";
import "./App.css";
import {
provisioningFormReducer,
provisioningFormInitialState,
ProvisioningContext,
} from "./state/provisioningForm";
import UserStep from "./components/UserStep";
import PlanStep from "./components/PlanStep";
import ConfirmStep from "./components/ConfirmStep";
import SuccessStep from "./components/SuccessStep";
const App = () => {
const [state, dispatch] = useReducer(
provisioningFormReducer,
provisioningFormInitialState
);
const getStep = () => {
switch (state.step) {
case "user":
return <UserStep />;
case "plan":
return <PlanStep />;
case "confirm":
return <ConfirmStep />;
case "success":
return <SuccessStep />;
default:
return null;
}
};
return (
<ProvisioningContext.Provider value={{ state, dispatch }}>
<main>{getStep()}</main>
</ProvisioningContext.Provider>
);
};
export default App;
import { useProvisioning } from "../state/provisioningForm";
const ConfirmStep = () => {
const { state, dispatch } = useProvisioning();
const handleConfirm = () => {
dispatch({
type: "NEXT_STEP",
});
};
const handlePrevious = () => {
dispatch({
type: "PREVIOUS_STEP",
});
};
return (
<>
<h1>Confirm details</h1>
<p>User: {state.user?.name}</p>
<p>Plan: {state.plan?.name}</p>
<button onClick={handlePrevious}>Previous</button>
<button onClick={handleConfirm}>Confirm</button>
</>
);
};
export default ConfirmStep;
import type { Plan } from "../state/provisioningForm";
const mockPlans: Plan[] = [
{
id: "4fa22f3e-9f11-47b8-b025-cc1671e6b7cb",
name: "Starter EU Plan",
limit: 1024, // 1GB
validity: 15,
price: 9,
},
{
id: "c1a9df68-2e60-4f5e-b1f5-181fd16b5a7f",
name: "Global Frequent Flyer",
limit: 10240, // 10GB
validity: 60,
price: 45,
},
{
id: "94e51b2e-3665-4a4e-a7b9-ef86e897586b",
name: "Unlimited 30-Day Plan",
limit: 999999, // Effectively unlimited
validity: 30,
price: 85,
},
{
id: "ed43e4c0-98aa-4c44-bcb2-712c06b0457d",
name: "Asia-Pacific 5GB",
limit: 5120,
validity: 20,
price: 25,
},
{
id: "21b4df15-7cf3-43a2-ae87-5fa57dffe228",
name: "Weekend Travel Plan",
limit: 750, // 750MB
validity: 3,
price: 4,
},
];
export default mockPlans;
import mockPlans from "../mocks/plans";
import { useProvisioning } from "../state/provisioningForm";
const PlanStep = () => {
const { state, dispatch } = useProvisioning();
const handlePlanChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const planId = event.target.value;
const selectedPlan = mockPlans.find((p) => p.id === planId);
dispatch({
type: "SET_PLAN",
value: selectedPlan,
});
};
const handlePrevious = () => {
dispatch({
type: "PREVIOUS_STEP",
});
};
const handleNext = () => {
dispatch({
type: "NEXT_STEP",
});
};
return (
<>
<h1>Select Plan</h1>
<select value={state.plan?.id || ""} onChange={handlePlanChange}>
<option value="" disabled>
Select a plan
</option>
{mockPlans.map((plan) => (
<option key={plan.id} value={plan.id}>
{plan.name} - ${plan.price} ({plan.limit / 1024} GB, {plan.validity}{" "}
days)
</option>
))}
</select>
<button onClick={handlePrevious}>Previous</button>
<button onClick={handleNext}>Next</button>
</>
);
};
export default PlanStep;
import { createContext, useContext } from "react";
type ProvisioningFormActionType =
| "SET_USER"
| "SET_PLAN"
| "NEXT_STEP"
| "PREVIOUS_STEP";
type Step = "user" | "plan" | "confirm" | "success";
export interface User {
id: string;
name: string;
email: string;
}
export interface Plan {
id: string;
name: string;
price: number;
limit: number;
validity: number;
}
interface ProvisioningFormState {
step: Step;
user: User | null;
plan: Plan | null;
}
interface ProvisioningFormAction {
type: ProvisioningFormActionType;
value?: User | Plan | Step;
}
const provisioningFormInitialState: ProvisioningFormState = {
step: "user",
user: null,
plan: null,
};
const nextStep = (state: ProvisioningFormState): Step => {
switch (state.step) {
case "user":
return "plan";
case "plan":
return "confirm";
case "confirm":
return "success";
default:
return "user";
}
};
const previousStep = (state: ProvisioningFormState): Step => {
switch (state.step) {
case "plan":
return "user";
case "confirm":
return "plan";
case "success":
return "confirm";
default:
return "user";
}
};
const provisioningFormReducer = (
state: ProvisioningFormState,
action: ProvisioningFormAction
) => {
switch (action.type) {
case "SET_USER":
return {
...state,
user: action.value as User,
};
case "SET_PLAN":
return {
...state,
plan: action.value as Plan,
};
case "NEXT_STEP":
return {
...state,
step: nextStep(state),
};
case "PREVIOUS_STEP":
return {
...state,
step: previousStep(state),
};
default:
return state;
}
};
const ProvisioningContext = createContext<{
state: ProvisioningFormState;
dispatch: React.Dispatch<ProvisioningFormAction>;
} | null>(null);
const useProvisioning = () => {
const context = useContext(ProvisioningContext);
if (!context) {
throw new Error(
"useProvisioning must be used within a ProvisioningContext.Provider"
);
}
return context;
};
export {
provisioningFormInitialState,
provisioningFormReducer,
ProvisioningContext,
useProvisioning,
};
const SuccessStep = () => {
return <h1>Provisioning Successful!</h1>;
};
export default SuccessStep;
import type { User } from "../state/provisioningForm";
const mockUsers: User[] = [
{
id: "a3e1c8a1-e0ff-4f32-b47f-1eb786f1abc3",
name: "Dr. Ada Lovelace",
email: "[email protected]",
},
{
id: "b9c3dff5-3e13-4e06-8c6f-5e2aa6a2d9f1",
name: "Alan Turing",
email: "[email protected]",
},
{
id: "f483da9d-c2c5-42b1-98b4-03d0f9f93755",
name: "Grace Hopper",
email: "[email protected]",
},
{
id: "91dfc0b6-342c-4f38-bb2b-fc25eb38d79a",
name: "Katherine Johnson",
email: "[email protected]",
},
{
id: "d7c52803-3a49-419b-a8d1-a3deedbeb79b",
name: "Margaret Hamilton",
email: "[email protected]",
},
{
id: "b16d93ec-3a5a-43c8-ae68-ba8e57c06113",
name: "Tim Berners-Lee",
email: "[email protected]",
},
{
id: "0dffe378-3b58-479e-8e30-fe24da539f7e",
name: "Linus Torvalds",
email: "[email protected]",
},
{
id: "bfe00135-f5f5-4696-b4c4-c817912b420c",
name: "Barbara Liskov",
email: "[email protected]",
},
{
id: "17bbf826-5d3f-4a1c-a1d9-293d8b09e92f",
name: "Edsger Dijkstra",
email: "[email protected]",
},
{
id: "fb0f3343-81bc-4d59-b787-5b5b8e521bbc",
name: "Radia Perlman",
email: "[email protected]",
},
{
id: "f6e5dfaf-a729-4a5a-b63a-55f78719c86e",
name: "Donald Knuth",
email: "[email protected]",
},
{
id: "3b65e37d-9e5f-414e-b8e2-325d9c504aad",
name: "Frances Allen",
email: "[email protected]",
},
{
id: "153f0ea3-cf28-4195-9c07-2434e36e0bd3",
name: "Jean Bartik",
email: "[email protected]",
},
{
id: "875a7d5d-3604-400a-9bd8-65013a1c68d4",
name: "Dennis Ritchie",
email: "[email protected]",
},
{
id: "feade69e-1a62-4a32-b497-2d4fef606f2c",
name: "Stephanie Shirley",
email: "[email protected]",
},
];
export default mockUsers;
import { useProvisioning } from "../state/provisioningForm";
import mockUsers from "../mocks/users";
const UserStep = () => {
const { state, dispatch } = useProvisioning();
const handleUserChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const userId = event.target.value;
const selectedUser = mockUsers.find((u) => u.id === userId);
dispatch({
type: "SET_USER",
value: selectedUser,
});
};
const handleNext = () => {
dispatch({
type: "NEXT_STEP",
});
};
return (
<>
<h1>Select User</h1>
<select value={state.user?.id || ""} onChange={handleUserChange}>
<option value="" disabled>
Select a user
</option>
{mockUsers.map((user) => (
<option key={user.id} value={user.id}>
{user.name}
</option>
))}
</select>
<button onClick={handleNext}>Next</button>
</>
);
};
export default UserStep;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment