login
This commit is contained in:
@ -11,8 +11,11 @@ const initialState = {
|
||||
needed: false,
|
||||
style: null,
|
||||
types: [],
|
||||
typeSizes: {},
|
||||
},
|
||||
accessControl: [],
|
||||
remoteButtons: 4,
|
||||
remoteQuantity: 1,
|
||||
};
|
||||
|
||||
function reducer(state, action) {
|
||||
@ -22,7 +25,7 @@ function reducer(state, action) {
|
||||
case 'SET_GROUND_LOOPS_NEEDED':
|
||||
return {
|
||||
...state,
|
||||
groundLoops: { needed: action.payload, style: null, types: [] },
|
||||
groundLoops: { needed: action.payload, style: null, types: [], typeSizes: {} },
|
||||
step: action.payload ? state.step : state.step + 1,
|
||||
};
|
||||
case 'SET_GROUND_LOOP_STYLE':
|
||||
@ -33,6 +36,12 @@ function reducer(state, action) {
|
||||
case 'TOGGLE_GROUND_LOOP_TYPE': {
|
||||
const id = action.payload;
|
||||
const exists = state.groundLoops.types.includes(id);
|
||||
const newTypeSizes = { ...state.groundLoops.typeSizes };
|
||||
if (!exists) {
|
||||
newTypeSizes[id] = '4x8';
|
||||
} else {
|
||||
delete newTypeSizes[id];
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
groundLoops: {
|
||||
@ -40,6 +49,7 @@ function reducer(state, action) {
|
||||
types: exists
|
||||
? state.groundLoops.types.filter((t) => t !== id)
|
||||
: [...state.groundLoops.types, id],
|
||||
typeSizes: newTypeSizes,
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -51,12 +61,28 @@ function reducer(state, action) {
|
||||
accessControl: exists
|
||||
? state.accessControl.filter((a) => a !== id)
|
||||
: [...state.accessControl, id],
|
||||
remoteButtons: id === 'remote-kit' && !exists ? 4 : state.remoteButtons,
|
||||
};
|
||||
}
|
||||
case 'SET_REMOTE_BUTTONS':
|
||||
return { ...state, remoteButtons: action.payload };
|
||||
case 'SET_REMOTE_QUANTITY':
|
||||
return { ...state, remoteQuantity: Math.max(1, action.payload) };
|
||||
case 'NEXT_STEP':
|
||||
return { ...state, step: Math.min(state.step + 1, 4) };
|
||||
case 'PREV_STEP':
|
||||
return { ...state, step: Math.max(state.step - 1, 1) };
|
||||
case 'SET_GROUND_LOOP_SIZE':
|
||||
return {
|
||||
...state,
|
||||
groundLoops: {
|
||||
...state.groundLoops,
|
||||
typeSizes: {
|
||||
...state.groundLoops.typeSizes,
|
||||
[action.payload.typeId]: action.payload.sizeId,
|
||||
},
|
||||
},
|
||||
};
|
||||
case 'GO_TO_STEP':
|
||||
return { ...state, step: Math.min(action.payload, 4) };
|
||||
case 'RESET':
|
||||
@ -66,9 +92,9 @@ function reducer(state, action) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function Wizard({ pricing }) {
|
||||
export default function Wizard({ pricing, onLogout }) {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
const { step, operator, groundLoops, accessControl } = state;
|
||||
const { step, operator, groundLoops, accessControl, remoteButtons, remoteQuantity } = state;
|
||||
|
||||
const steps = [
|
||||
{ num: 1, label: 'Operator' },
|
||||
@ -79,7 +105,17 @@ export default function Wizard({ pricing }) {
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto px-4 py-8">
|
||||
<div className="text-center mb-8">
|
||||
<div className="text-center mb-8 relative">
|
||||
<button
|
||||
onClick={onLogout}
|
||||
className="absolute right-0 top-0 text-xs text-gray-400 hover:text-gray-600 transition-colors flex items-center gap-1"
|
||||
title="Logout"
|
||||
>
|
||||
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
|
||||
</svg>
|
||||
Logout
|
||||
</button>
|
||||
<h1 className="text-3xl font-bold text-gray-900">
|
||||
Gate Operator Quotation System
|
||||
</h1>
|
||||
@ -141,12 +177,15 @@ export default function Wizard({ pricing }) {
|
||||
|
||||
{step === 2 && (
|
||||
<StepGroundLoops
|
||||
detectors={pricing.loopDetectors}
|
||||
styles={pricing.groundLoopStyles}
|
||||
sizes={pricing.groundLoopSizes}
|
||||
types={pricing.groundLoopTypes}
|
||||
value={groundLoops}
|
||||
onSetNeeded={(needed) => dispatch({ type: 'SET_GROUND_LOOPS_NEEDED', payload: needed })}
|
||||
onSetStyle={(id) => dispatch({ type: 'SET_GROUND_LOOP_STYLE', payload: id })}
|
||||
onToggleType={(id) => dispatch({ type: 'TOGGLE_GROUND_LOOP_TYPE', payload: id })}
|
||||
onSetSize={(typeId, sizeId) => dispatch({ type: 'SET_GROUND_LOOP_SIZE', payload: { typeId, sizeId } })}
|
||||
onNext={() => dispatch({ type: 'NEXT_STEP' })}
|
||||
onBack={() => dispatch({ type: 'PREV_STEP' })}
|
||||
/>
|
||||
@ -155,8 +194,13 @@ export default function Wizard({ pricing }) {
|
||||
{step === 3 && (
|
||||
<StepAccessControl
|
||||
accessControl={pricing.accessControl}
|
||||
remoteButtonOptions={pricing.remoteButtonOptions}
|
||||
selected={accessControl}
|
||||
remoteButtons={remoteButtons}
|
||||
remoteQuantity={remoteQuantity}
|
||||
onToggle={(id) => dispatch({ type: 'TOGGLE_ACCESS_CONTROL', payload: id })}
|
||||
onSetRemoteButtons={(count) => dispatch({ type: 'SET_REMOTE_BUTTONS', payload: count })}
|
||||
onSetRemoteQuantity={(qty) => dispatch({ type: 'SET_REMOTE_QUANTITY', payload: qty })}
|
||||
onBack={() => dispatch({ type: 'PREV_STEP' })}
|
||||
onNext={() => dispatch({ type: 'NEXT_STEP' })}
|
||||
/>
|
||||
@ -165,7 +209,7 @@ export default function Wizard({ pricing }) {
|
||||
{step === 4 && (
|
||||
<QuoteSummary
|
||||
pricing={pricing}
|
||||
selections={{ operator, groundLoops, accessControl }}
|
||||
selections={{ operator, groundLoops, accessControl, remoteButtons, remoteQuantity }}
|
||||
onBack={() => dispatch({ type: 'PREV_STEP' })}
|
||||
onNew={() => dispatch({ type: 'RESET' })}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user