Skip to content

Commit 58a1be7

Browse files
committed
Drops mock auth, reorganizes UI, adds webhook tab
Removes mock user endpoints to streamline authentication Extracts routing into a dedicated component for maintainability Centralizes style definitions and simplifies logout flow Includes new webhook tab to enhance workflow control
1 parent edea552 commit 58a1be7

File tree

8 files changed

+296
-174
lines changed

8 files changed

+296
-174
lines changed

server/src/index.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,12 @@ process.on('unhandledRejection', (reason) => {
4848
console.error('Unhandled rejection:', reason);
4949
});
5050

51-
// Mock user for auth endpoints
52-
const mockUser = {
53-
id: "user-1",
54-
name: "Demo User",
55-
avatar:
56-
"https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&s=128",
57-
};
5851

5952
// API mounted under /api to make it easy to host frontend and backend together
6053
app.get("/api/health", (_req: Request, res: Response) => {
6154
res.json({ status: "ok", uptime: process.uptime() });
6255
});
6356

64-
app.get("/api/me", (_req: Request, res: Response) => {
65-
res.json({ authenticated: true, profile: mockUser });
66-
});
67-
68-
app.post("/api/logout", (_req: Request, res: Response) => {
69-
res.json({ ok: true });
70-
});
7157

7258
// Register webhook-related routes (event store, SSE, diagnostics)
7359
registerWebhookRoutes(app);

src/App.tsx

Lines changed: 15 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { usePersistedSelections } from './hooks/usePersistedSelections';
1919
import AppProviders from './app/Providers';
2020
import AppShell from './app/AppShell';
2121

22-
type TabType = 'edit' | 'documentation';
22+
type TabType = 'edit' | 'documentation' | 'webhook';
2323

2424
interface Bay {
2525
id: string;
@@ -269,7 +269,10 @@ export default function App() {
269269
});
270270
if (mutated) {
271271
// dispatch minimal updates via LOAD_SCRIPT to reuse validation effect
272-
dispatch({ type: 'LOAD_SCRIPT', script: { activities: repairedActivities } });
272+
// repairedActivities may be a freshly-mapped array and TypeScript
273+
// can be conservative about subtype narrowing here. Cast to ScriptData
274+
// to satisfy the reducer action shape while preserving runtime value.
275+
dispatch({ type: 'LOAD_SCRIPT', script: { activities: repairedActivities } as unknown as ScriptData });
273276
}
274277
setMigrationComplete(true);
275278
}, [script.activities, migrationComplete]);
@@ -583,56 +586,19 @@ export default function App() {
583586

584587
if (logoutComplete) {
585588
return (
586-
<div style={{
587-
height: '100vh',
588-
display: 'flex',
589-
flexDirection: 'column',
590-
alignItems: 'center',
591-
justifyContent: 'center',
592-
backgroundColor: '#f5f5f5',
593-
fontFamily: 'system-ui, -apple-system, sans-serif'
594-
}}>
595-
<div style={{
596-
padding: '2rem',
597-
backgroundColor: 'white',
598-
borderRadius: '8px',
599-
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
600-
textAlign: 'center',
601-
maxWidth: '400px'
602-
}}>
603-
<div style={{ fontSize: '48px', marginBottom: '1rem' }}></div>
604-
<h2 style={{ margin: '0 0 1rem 0', color: '#333' }}>Logout Successful</h2>
605-
<p style={{ margin: '0', color: '#666' }}>
589+
<div className="logout-center">
590+
<div className="logout-box">
591+
<div className="logout-emoji"></div>
592+
<h2 className="logout-heading">Logout Successful</h2>
593+
<p className="logout-text">
606594
You have been logged out successfully.<br/>
607595
Redirecting to login page...
608596
</p>
609-
<div style={{
610-
marginTop: '1rem',
611-
padding: '0.5rem',
612-
backgroundColor: '#f8f9fa',
613-
borderRadius: '4px',
614-
fontSize: '0.9em',
615-
color: '#666'
616-
}}>
617-
<div className="spinner" style={{
618-
display: 'inline-block',
619-
width: '16px',
620-
height: '16px',
621-
border: '2px solid #ddd',
622-
borderTop: '2px solid #007acc',
623-
borderRadius: '50%',
624-
animation: 'spin 1s linear infinite',
625-
marginRight: '8px'
626-
}}></div>
597+
<div className="logout-spinner-wrap">
598+
<div className="logout-spinner" aria-hidden="true"></div>
627599
Please wait...
628600
</div>
629601
</div>
630-
<style>{`
631-
@keyframes spin {
632-
0% { transform: rotate(0deg); }
633-
100% { transform: rotate(360deg); }
634-
}
635-
`}</style>
636602
</div>
637603
);
638604
}
@@ -649,12 +615,14 @@ export default function App() {
649615
activeTab={activeTab}
650616
setActiveTab={setActiveTab}
651617
state={state}
618+
selectedNode={selectedNode}
652619
script={script}
653620
isValid={isValid}
654-
validationErrors={validationErrors.errors || validationErrors}
621+
validationErrors={validationErrors}
655622
selections={selections}
656623
selectedLocation={selectedLocation}
657624
selectedBayObj={selectedBayObj}
625+
parentActivityForAdd={parentActivityForAdd}
658626
onLoadScript={loadScript}
659627
onDownloadScript={downloadScript}
660628
onLocationSelect={handleLocationSelect}

src/app/AppShell.tsx

Lines changed: 29 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import { ScriptEditor } from '../components/ScriptEditor';
77
import { NodeEditor } from '../components/NodeEditor';
88
import { DocViewer } from '../components/DocViewer';
99
import WebhookView from '../components/WebhookView';
10+
import Routes from './Routes';
11+
import { ScriptData, Activity, Step } from '../types';
12+
import { SidebarProps } from '../components/Sidebar';
1013

1114
export type TabType = 'edit' | 'documentation' | 'webhook';
1215

@@ -19,12 +22,14 @@ export interface AppShellProps {
1922
setActiveTab: (t: TabType) => void;
2023
// editor state and handlers (kept generic to avoid tight coupling in this step)
2124
state: any;
22-
script: any;
25+
selectedNode?: Activity | Step | null;
26+
script: ScriptData;
2327
isValid: boolean;
24-
validationErrors: any[];
28+
validationErrors: string[];
2529
selections: any;
2630
selectedLocation: any;
2731
selectedBayObj: any;
32+
parentActivityForAdd?: any;
2833
onLoadScript: () => void;
2934
onDownloadScript: () => void;
3035
onLocationSelect: (l: any) => void;
@@ -46,14 +51,17 @@ export const AppShell: React.FC<AppShellProps> = (props) => {
4651
selections,
4752
selectedLocation,
4853
selectedBayObj,
54+
parentActivityForAdd,
4955
onLoadScript,
5056
onDownloadScript,
5157
onLocationSelect,
5258
onBaySelect,
5359
dispatch
5460
} = props;
5561

56-
const selectedNode = (() => {
62+
// Prefer a hydrated selected node object from the top-level App when available
63+
const effectiveSelectedNode = (() => {
64+
if (props.selectedNode !== undefined) return props.selectedNode;
5765
try { return (state && state.selectedRef && state.selectedRef.kind !== 'script') ? state.selectedRef : null; } catch { return null; }
5866
})();
5967

@@ -69,75 +77,24 @@ export const AppShell: React.FC<AppShellProps> = (props) => {
6977
onTabChange={setActiveTab}
7078
/>
7179

72-
{activeTab === 'edit' ? (
73-
<div className="tree-flex">
74-
<DialogManager
75-
// dialog props are expected to be provided via dispatch or parent
76-
showActivityDialog={false}
77-
showStepDialog={false}
78-
onCloseActivityDialog={() => {}}
79-
onCloseStepDialog={() => {}}
80-
onAddActivity={() => {}}
81-
onAddStep={() => {}}
82-
parentActivityForAdd={undefined}
83-
/>
84-
<Sidebar
85-
script={script}
86-
selectedRef={state.selectedRef}
87-
selectedNode={selectedNode}
88-
isValid={isValid}
89-
validationErrors={validationErrors}
90-
selectedFacilityId={selectedFacilityId}
91-
selectedLocationId={selectedLocation?.id || null}
92-
persistedLocationId={selections?.locationId || null}
93-
selectedBayId={selectedBayObj?.id || null}
94-
persistedBayId={selections?.bayId || null}
95-
selectedBayObj={selectedBayObj}
96-
onLoadScript={onLoadScript}
97-
onDownloadScript={onDownloadScript}
98-
onLocationSelect={onLocationSelect}
99-
onBaySelect={onBaySelect}
100-
onCloneSelected={() => dispatch({ type: 'CLONE_SELECTED' })}
101-
onShowActivityDialog={() => {}}
102-
onShowStepDialog={() => {}}
103-
onSelectScript={() => dispatch({ type: 'SELECT_SCRIPT' })}
104-
onSelectActivity={(activityId: string) => dispatch({ type: 'SELECT_ACTIVITY', activityId })}
105-
onSelectStep={(activityId: string, stepId: string) => dispatch({ type: 'SELECT_STEP', activityId, stepId })}
106-
onDeleteActivity={(id: string) => dispatch({ type: 'DELETE_ACTIVITY', activityId: id })}
107-
onDeleteStep={(activityId: string, stepId: string) => dispatch({ type: 'DELETE_STEP', activityId, stepId })}
108-
parentActivityForAdd={undefined}
109-
/>
110-
111-
<div className="tree-main">
112-
{state.selectedRef?.kind === 'script' ? (
113-
<>
114-
<h2>Script Configuration</h2>
115-
<ScriptEditor
116-
script={script}
117-
onChange={(s: any) => dispatch({ type: 'LOAD_SCRIPT', script: s })}
118-
/>
119-
<pre>{JSON.stringify(script, null, 2)}</pre>
120-
</>
121-
) : selectedNode ? (
122-
<NodeEditor
123-
node={selectedNode}
124-
onUpdateActivity={(activityId: string, patch: any) => dispatch({ type: 'UPDATE_ACTIVITY', activityId, patch })}
125-
onUpdateStep={(stepId: string, patch: any) => dispatch({ type: 'UPDATE_STEP', stepId, patch })}
126-
/>
127-
) : (
128-
<div className="empty-node-editor">Select a node to edit its details.</div>
129-
)}
130-
</div>
131-
</div>
132-
) : activeTab === 'documentation' ? (
133-
<div className="documentation-flex">
134-
<DocViewer />
135-
</div>
136-
) : activeTab === 'webhook' ? (
137-
<div className="documentation-flex">
138-
<WebhookView selectedBayDbId={selectedBayObj?.dbId ?? null} />
139-
</div>
140-
) : null}
80+
<Routes
81+
activeTab={activeTab}
82+
state={state}
83+
selectedNode={effectiveSelectedNode ?? null}
84+
script={script}
85+
isValid={isValid}
86+
validationErrors={validationErrors}
87+
selections={selections}
88+
selectedFacilityId={selectedFacilityId}
89+
parentActivityForAdd={parentActivityForAdd}
90+
selectedLocation={selectedLocation}
91+
selectedBayObj={selectedBayObj}
92+
onLoadScript={onLoadScript}
93+
onDownloadScript={onDownloadScript}
94+
onLocationSelect={onLocationSelect}
95+
onBaySelect={onBaySelect}
96+
dispatch={dispatch}
97+
/>
14198
</div>
14299
);
143100
};

0 commit comments

Comments
 (0)