ConfigBuilder.tsx•4.91 kB
import React from 'react';
import CodeBlock from './CodeBlock';
interface FieldState {
  hostname: string;
  username: string;
  password: string;
  clientId: string;
  clientSecret: string;
  codeVersion: string;
  siteId: string;
  minimal: boolean;
}
const initial: FieldState = {
  hostname: 'dev01-sandbox.us01.dx.commercecloud.salesforce.com',
  username: 'your-username',
  password: 'your-password',
  clientId: '',
  clientSecret: '',
  codeVersion: 'version1',
  siteId: 'RefArch',
  minimal: true
};
const labelCls = 'block text-xs font-semibold uppercase tracking-wide text-gray-600 mb-1';
const inputCls = 'w-full rounded-lg border border-gray-300 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 px-3 py-2 text-sm bg-white';
const pillBase = 'px-3 py-1.5 rounded-full text-xs font-medium transition border flex items-center gap-1';
export const ConfigBuilder: React.FC = () => {
  const [state, setState] = React.useState<FieldState>(initial);
  const toggleMinimal = () => setState(s => ({ ...s, minimal: !s.minimal }));
  const json = React.useMemo(() => {
    const base: Record<string, string> = {
      hostname: state.hostname,
      username: state.username,
      password: state.password
    };
    if (!state.minimal) {
      if (state.clientId) base['client-id'] = state.clientId;
      if (state.clientSecret) base['client-secret'] = state.clientSecret;
      if (state.codeVersion) base['code-version'] = state.codeVersion;
      if (state.siteId) base['site-id'] = state.siteId;
    }
    return JSON.stringify(base, null, 2);
  }, [state]);
  const update = (k: keyof FieldState) => (e: React.ChangeEvent<HTMLInputElement>) => setState(s => ({ ...s, [k]: e.target.value }));
  return (
    <div className="space-y-6">
      <div className="flex flex-wrap gap-3 items-center">
        <button onClick={toggleMinimal} className={`${pillBase} ${state.minimal ? 'bg-blue-600 text-white border-blue-600 shadow' : 'bg-white text-gray-700 border-gray-200 hover:border-blue-400'}`}
          aria-pressed={state.minimal}>
          {state.minimal ? 'Minimal Config' : 'Show Minimal'}
        </button>
        <button onClick={toggleMinimal} className={`${pillBase} ${!state.minimal ? 'bg-purple-600 text-white border-purple-600 shadow' : 'bg-white text-gray-700 border-gray-200 hover:border-purple-400'}`}
          aria-pressed={!state.minimal}>
          {!state.minimal ? 'Advanced Config' : 'Show Advanced'}
        </button>
        <span className="text-xs text-gray-500">Toggle to include OAuth + code/site fields</span>
      </div>
      <div className="grid md:grid-cols-2 gap-6">
        <div className="space-y-4">
          <div>
            <label className={labelCls}>Hostname *</label>
            <input value={state.hostname} onChange={update('hostname')} className={inputCls} />
          </div>
          <div className="grid grid-cols-2 gap-4">
            <div>
              <label className={labelCls}>Username *</label>
              <input value={state.username} onChange={update('username')} className={inputCls} />
            </div>
            <div>
              <label className={labelCls}>Password *</label>
              <input type="password" value={state.password} onChange={update('password')} className={inputCls} />
            </div>
          </div>
          {!state.minimal && (
            <>
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className={labelCls}>Client ID</label>
                  <input value={state.clientId} onChange={update('clientId')} className={inputCls} />
                </div>
                <div>
                  <label className={labelCls}>Client Secret</label>
                  <input type="password" value={state.clientSecret} onChange={update('clientSecret')} className={inputCls} />
                </div>
              </div>
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className={labelCls}>Code Version</label>
                  <input value={state.codeVersion} onChange={update('codeVersion')} className={inputCls} />
                </div>
                <div>
                  <label className={labelCls}>Site ID</label>
                  <input value={state.siteId} onChange={update('siteId')} className={inputCls} />
                </div>
              </div>
            </>
          )}
          <p className="text-[11px] text-gray-500">* Required for WebDAV + log tools. Client credentials unlock Data API features.</p>
        </div>
        <div>
          <CodeBlock language="json" code={json} />
          <p className="text-xs text-gray-500 -mt-4">Copy & save as <code className="font-mono">dw.json</code> then run with <code className="font-mono">--dw-json ./dw.json</code></p>
        </div>
      </div>
    </div>
  );
};
export default ConfigBuilder;