3import { useState, useEffect } from 'react';
4import Link from 'next/link';
12 storeServerMesh: { [profile: string]: boolean };
13 initialUi: { [profile: string]: string };
16 commandsForLane: string;
17 installCommands: string;
20export default function StoreConfigurationPage() {
21 const [uiOptions, setUiOptions] = useState<UiOption[]>([]);
22 const [settings, setSettings] = useState<Settings>({
30 const [loading, setLoading] = useState(true);
32 const profiles = ['0', '1', '2', '3', '4', '5', '6', '7', '8'];
38 const loadData = async () => {
42 // In production, this would call: /api/v1/elink/ui-list
43 // For now, using placeholder data
45 { id: 1, name: 'Default POS Interface' },
46 { id: 2, name: 'Touch Screen UI' },
47 { id: 3, name: 'Mobile UI' },
48 { id: 4, name: 'Quick Service UI' },
49 { id: 5, name: 'Restaurant UI' }
52 // Load current settings
53 // In production, this would call: /api/v1/elink/lane-settings
54 const defaultSettings: Settings = {
63 profiles.forEach(p => {
64 defaultSettings.storeServerMesh[p] = true;
65 defaultSettings.initialUi[p] = '';
68 setSettings(defaultSettings);
70 console.error('Error loading configuration:', error);
71 alert('Failed to load configuration data');
77 const handleToggleChange = (profile: string, value: boolean) => {
78 setSettings(prev => ({
81 ...prev.storeServerMesh,
85 saveSetting('StoreServerAllowMesh', profile, value);
88 const handleUiChange = (profile: string, value: string) => {
89 setSettings(prev => ({
96 saveSetting('LaneCoden400.UserInterfaceN', profile, value);
99 const handleDirectMeshChange = (value: boolean) => {
100 setSettings(prev => ({ ...prev, directMesh: value }));
101 saveSetting('LaneInstallDirectMesh', '0', value);
104 const handleDefaultUiChange = (value: string) => {
105 setSettings(prev => ({ ...prev, defaultUi: value }));
106 saveSetting('LaneCoden400.UserInterfaceN', '0', value);
109 const handleCommandsChange = (value: string) => {
110 setSettings(prev => ({ ...prev, commandsForLane: value }));
113 const handleInstallCommandsChange = (value: string) => {
114 setSettings(prev => ({ ...prev, installCommands: value }));
117 const saveSetting = async (settingName: string, profile: string, value: any) => {
119 // In production, this would call: /api/v1/elink/lane-settings
120 // POST with { settingName, profile, value }
121 console.log('Saving:', settingName, profile, value);
123 // Placeholder - in production would be actual API call
124 // await apiClient.saveLaneSetting(settingName, profile, value);
126 console.error('Error saving setting:', error);
127 alert('Failed to save setting');
131 const saveTextAreaSetting = async (settingName: string) => {
132 const value = settingName === 'LaneCoden400.FposAllCtl'
133 ? settings.commandsForLane
134 : settings.installCommands;
136 await saveSetting(settingName, '0', value);
137 alert('Commands saved successfully');
142 <div className="p-8">
143 <div className="text-center">Loading configuration...</div>
149 <div className="min-h-screen bg-bg">
151 <div className="bg-[#00946b] text-white p-4 shadow-lg">
152 <div className="flex items-center">
154 src="/logo/fieldpine-logo.png"
156 className="w-48 h-auto rounded-lg shadow-lg mr-6"
157 onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}
159 <div className="text-sm">
160 [ <Link href="/pages/home" className="hover:underline">Home</Link> ]
161 {' '}[ <Link href="/pages/settings/stores" className="hover:underline">Stores</Link>
162 {' '}<span className="text-xl">→</span> ] Configure Lane Definition
168 <div className="bg-surface border-b-2 border-[#00543b] p-4">
169 <h1 className="text-3xl font-bold text-text">Configure Lane Definitions</h1>
172 <div className="p-6">
173 {/* Profile Settings Table */}
174 <div className="bg-surface rounded-lg shadow-md overflow-x-auto mt-8">
175 <table className="w-full border-collapse">
177 <tr className="bg-[#00543b] text-white">
178 <th className="p-3 text-left border border-border">Setting</th>
180 <th key={p} className="p-3 text-center border border-border">
181 {p === '0' ? 'No Profile' : `Profile ${p}`}
184 <th className="p-3 text-center border border-border">Version</th>
188 {/* Store Server as Database */}
189 <tr className="hover:bg-surface-2">
190 <td className="p-3 border border-border font-semibold">
191 Store Server as Database
194 <td key={p} className="p-3 border border-border text-center">
195 <label className="relative inline-flex items-center cursor-pointer">
198 className="sr-only peer"
199 checked={settings.storeServerMesh[p] || false}
200 onChange={(e) => handleToggleChange(p, e.target.checked)}
202 <div className="w-11 h-6 bg-surface-2 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-[#00543b]/30 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-surface after:border-border after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-[#00543b]"></div>
206 <td className="p-3 border border-border text-center text-sm text-muted">
211 <td colSpan={11} className="p-2 bg-surface-2 text-sm text-muted border border-border">
212 Can a store server act as the primary database for lanes within the store. This is generally enabled.
216 {/* Initial User Interface on Install */}
217 <tr className="hover:bg-surface-2">
218 <td className="p-3 border border-border font-semibold">
219 Initial User Interface on Install
222 <td key={p} className="p-3 border border-border">
224 className="w-full px-2 py-1 border border-border rounded focus:ring-2 focus:ring-[#00543b] focus:border-[#00543b]"
225 value={settings.initialUi[p] || ''}
226 onChange={(e) => handleUiChange(p, e.target.value)}
228 <option value="">--System default</option>
229 {uiOptions.map(ui => (
230 <option key={ui.id} value={ui.id}>{ui.name}</option>
235 <td className="p-3 border border-border text-center text-sm text-muted">
240 <td colSpan={11} className="p-2 bg-surface-2 text-sm text-muted border border-border">
241 When a new lane is installed, which User Interface should it initially be assigned
248 {/* Fieldpine.com Lanes Configuration */}
249 <div className="bg-surface rounded-lg shadow-md p-6 mt-8">
250 <h2 className="text-2xl font-bold text-text mb-6">
251 Configuration for Fieldpine.com Lanes
254 {/* Direct Mesh Communication */}
255 <div className="flex items-start gap-4 mb-6 pb-6 border-b border-border">
256 <label className="relative inline-flex items-center cursor-pointer mt-1">
259 className="sr-only peer"
260 checked={settings.directMesh}
261 onChange={(e) => handleDirectMeshChange(e.target.checked)}
263 <div className="w-14 h-7 bg-surface-2 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-[#00543b]/30 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-surface after:border-border after:border after:rounded-full after:h-6 after:w-6 after:transition-all peer-checked:bg-[#00543b]"></div>
266 <h3 className="font-semibold text-lg text-text">
267 Allow PosGreen lanes to communicate directly to Fieldpine.com
269 <p className="text-muted text-sm mt-1">
270 Lanes that do this are charged on a usage volume basis
275 {/* User Interface Selection */}
276 <div className="mb-6">
277 <h3 className="font-semibold text-text mb-2">User Interface</h3>
279 className="w-full max-w-md px-3 py-2 border border-border rounded-lg focus:ring-2 focus:ring-[#00543b] focus:border-[#00543b]"
280 value={settings.defaultUi}
281 onChange={(e) => handleDefaultUiChange(e.target.value)}
283 <option value="">--System default</option>
284 {uiOptions.map(ui => (
285 <option key={ui.id} value={ui.id}>{ui.name}</option>
288 <p className="text-muted text-sm mt-2">
289 The User Interface (aka "UI" or "skin") controls both how the screen the Pos displays and operates.
293 {/* Commands for Each Lane */}
294 <div className="mb-6">
295 <h3 className="font-semibold text-text mb-2">Commands for each lane</h3>
298 className="w-full px-3 py-2 border border-border rounded-lg focus:ring-2 focus:ring-[#00543b] focus:border-[#00543b] font-mono text-sm"
299 placeholder="Configuration Commands for each lane"
300 value={settings.commandsForLane}
301 onChange={(e) => handleCommandsChange(e.target.value)}
302 onBlur={() => saveTextAreaSetting('LaneCoden400.FposAllCtl')}
306 {/* Install Commands for Each Lane */}
307 <div className="mb-6">
308 <h3 className="font-semibold text-text mb-2">Install Commands for each lane</h3>
309 <p className="text-muted text-sm mb-2">
310 These commands are deployed to the lane on initial install only.
314 className="w-full px-3 py-2 border border-border rounded-lg focus:ring-2 focus:ring-[#00543b] focus:border-[#00543b] font-mono text-sm"
315 placeholder="Configuration Commands for each lane"
316 value={settings.installCommands}
317 onChange={(e) => handleInstallCommandsChange(e.target.value)}
318 onBlur={() => saveTextAreaSetting('LaneCoden400.FposBlankCtl')}
324 <div className="mt-6">
326 href="/pages/settings/stores"
327 className="inline-flex items-center px-6 py-3 bg-muted text-white rounded-lg hover:bg-muted/90 transition-colors"