deepwiki-open / src /components /ConfigurationModal.tsx
bhavinmatariya's picture
Initial complete codebase with Git LFS for binary files
8e0dd55
'use client';
import React, { useState } from 'react';
import { useLanguage } from '@/contexts/LanguageContext';
import UserSelector from './UserSelector';
import TokenInput from './TokenInput';
interface ConfigurationModalProps {
isOpen: boolean;
onClose: () => void;
// Repository input
repositoryInput: string;
// Language selection
selectedLanguage: string;
setSelectedLanguage: (value: string) => void;
supportedLanguages: Record<string, string>;
// Wiki type options
isComprehensiveView: boolean;
setIsComprehensiveView: (value: boolean) => void;
// Model selection
provider: string;
setProvider: (value: string) => void;
model: string;
setModel: (value: string) => void;
isCustomModel: boolean;
setIsCustomModel: (value: boolean) => void;
customModel: string;
setCustomModel: (value: string) => void;
// Platform selection
selectedPlatform: 'github' | 'gitlab' | 'bitbucket';
setSelectedPlatform: (value: 'github' | 'gitlab' | 'bitbucket') => void;
// Access token
accessToken: string;
setAccessToken: (value: string) => void;
// File filter options
excludedDirs: string;
setExcludedDirs: (value: string) => void;
excludedFiles: string;
setExcludedFiles: (value: string) => void;
includedDirs: string;
setIncludedDirs: (value: string) => void;
includedFiles: string;
setIncludedFiles: (value: string) => void;
// Form submission
onSubmit: () => void;
isSubmitting: boolean;
// Authentication
authRequired?: boolean;
authCode?: string;
setAuthCode?: (code: string) => void;
isAuthLoading?: boolean;
}
export default function ConfigurationModal({
isOpen,
onClose,
repositoryInput,
selectedLanguage,
setSelectedLanguage,
supportedLanguages,
isComprehensiveView,
setIsComprehensiveView,
provider,
setProvider,
model,
setModel,
isCustomModel,
setIsCustomModel,
customModel,
setCustomModel,
selectedPlatform,
setSelectedPlatform,
accessToken,
setAccessToken,
excludedDirs,
setExcludedDirs,
excludedFiles,
setExcludedFiles,
includedDirs,
setIncludedDirs,
includedFiles,
setIncludedFiles,
onSubmit,
isSubmitting,
authRequired,
authCode,
setAuthCode,
isAuthLoading
}: ConfigurationModalProps) {
const { messages: t } = useLanguage();
// Show token section state
const [showTokenSection, setShowTokenSection] = useState(false);
if (!isOpen) return null;
return (
<div className="fixed inset-0 z-50 overflow-y-auto">
<div className="flex min-h-screen items-center justify-center p-4 text-center bg-black/50">
<div className="relative transform overflow-hidden rounded-lg bg-[var(--card-bg)] text-left shadow-xl transition-all sm:my-8 sm:max-w-2xl sm:w-full">
{/* Modal header with close button */}
<div className="flex items-center justify-between px-6 py-4 border-b border-[var(--border-color)]">
<h3 className="text-lg font-medium text-[var(--accent-primary)]">
<span className="text-[var(--accent-primary)]">{t.form?.configureWiki || 'Configure Wiki'}</span>
</h3>
<button
type="button"
onClick={onClose}
className="text-[var(--muted)] hover:text-[var(--foreground)] focus:outline-none transition-colors"
>
<svg className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
{/* Modal body */}
<div className="p-6 max-h-[70vh] overflow-y-auto">
{/* Repository info */}
<div className="mb-4">
<label className="block text-sm font-medium text-[var(--foreground)] mb-2">
{t.form?.repository || 'Repository'}
</label>
<div className="bg-[var(--background)]/70 p-3 rounded-md border border-[var(--border-color)] text-sm text-[var(--foreground)]">
{repositoryInput}
</div>
</div>
{/* Language selection */}
<div className="mb-4">
<label htmlFor="language-select" className="block text-sm font-medium text-[var(--foreground)] mb-2">
{t.form?.wikiLanguage || 'Wiki Language'}
</label>
<select
id="language-select"
value={selectedLanguage}
onChange={(e) => setSelectedLanguage(e.target.value)}
className="input-japanese block w-full px-3 py-2 text-sm rounded-md bg-transparent text-[var(--foreground)] focus:outline-none focus:border-[var(--accent-primary)]"
>
{
Object.entries(supportedLanguages).map(([key, value])=> <option key={key} value={key}>{value}</option>)
}
</select>
</div>
{/* Wiki Type Selector - more compact version */}
<div className="mb-4">
<label className="block text-sm font-medium text-[var(--foreground)] mb-2">
{t.form?.wikiType || 'Wiki Type'}
</label>
<div className="flex gap-3">
<button
type="button"
onClick={() => setIsComprehensiveView(true)}
className={`flex-1 flex items-center justify-between p-2 rounded-md border transition-colors ${
isComprehensiveView
? 'bg-[var(--accent-primary)]/10 border-[var(--accent-primary)]/30 text-[var(--accent-primary)]'
: 'bg-[var(--background)]/50 border-[var(--border-color)] text-[var(--foreground)] hover:bg-[var(--background)]'
}`}
>
<div className="flex items-center">
<div className="text-left">
<div className="font-medium text-sm">{t.form?.comprehensive || 'Comprehensive'}</div>
<div className="text-xs opacity-80">
{t.form?.comprehensiveDescription || 'Detailed wiki with structured sections'}
</div>
</div>
</div>
{isComprehensiveView && (
<div className="ml-2 h-4 w-4 rounded-full bg-[var(--accent-primary)]/20 flex items-center justify-center">
<div className="h-2 w-2 rounded-full bg-[var(--accent-primary)]"></div>
</div>
)}
</button>
<button
type="button"
onClick={() => setIsComprehensiveView(false)}
className={`flex-1 flex items-center justify-between p-2 rounded-md border transition-colors ${
!isComprehensiveView
? 'bg-[var(--accent-primary)]/10 border-[var(--accent-primary)]/30 text-[var(--accent-primary)]'
: 'bg-[var(--background)]/50 border-[var(--border-color)] text-[var(--foreground)] hover:bg-[var(--background)]'
}`}
>
<div className="flex items-center">
<div className="text-left">
<div className="font-medium text-sm">{t.form?.concise || 'Concise'}</div>
<div className="text-xs opacity-80">
{t.form?.conciseDescription || 'Simplified wiki with fewer pages'}
</div>
</div>
</div>
{!isComprehensiveView && (
<div className="ml-2 h-4 w-4 rounded-full bg-[var(--accent-primary)]/20 flex items-center justify-center">
<div className="h-2 w-2 rounded-full bg-[var(--accent-primary)]"></div>
</div>
)}
</button>
</div>
</div>
{/* Model Selector */}
<div className="mb-4">
<UserSelector
provider={provider}
setProvider={setProvider}
model={model}
setModel={setModel}
isCustomModel={isCustomModel}
setIsCustomModel={setIsCustomModel}
customModel={customModel}
setCustomModel={setCustomModel}
showFileFilters={true}
excludedDirs={excludedDirs}
setExcludedDirs={setExcludedDirs}
excludedFiles={excludedFiles}
setExcludedFiles={setExcludedFiles}
includedDirs={includedDirs}
setIncludedDirs={setIncludedDirs}
includedFiles={includedFiles}
setIncludedFiles={setIncludedFiles}
/>
</div>
{/* Access token section using TokenInput component */}
<TokenInput
selectedPlatform={selectedPlatform}
setSelectedPlatform={setSelectedPlatform}
accessToken={accessToken}
setAccessToken={setAccessToken}
showTokenSection={showTokenSection}
onToggleTokenSection={() => setShowTokenSection(!showTokenSection)}
allowPlatformChange={true}
/>
{/* Authorization Code Input */}
{isAuthLoading && (
<div className="mb-4 p-3 bg-[var(--background)]/50 rounded-md border border-[var(--border-color)] text-sm text-[var(--muted)]">
Loading authentication status...
</div>
)}
{!isAuthLoading && authRequired && (
<div className="mb-4 p-4 bg-[var(--background)]/50 rounded-md border border-[var(--border-color)]">
<label htmlFor="authCode" className="block text-sm font-medium text-[var(--foreground)] mb-2">
{t.form?.authorizationCode || 'Authorization Code'}
</label>
<input
type="password"
id="authCode"
value={authCode || ''}
onChange={(e) => setAuthCode?.(e.target.value)}
className="input-japanese block w-full px-3 py-2 text-sm rounded-md bg-transparent text-[var(--foreground)] focus:outline-none focus:border-[var(--accent-primary)]"
placeholder="Enter your authorization code"
/>
<div className="flex items-center mt-2 text-xs text-[var(--muted)]">
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 mr-1 text-[var(--muted)]"
fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
{t.form?.authorizationRequired || 'Authentication is required to generate the wiki.'}
</div>
</div>
)}
</div>
{/* Modal footer */}
<div className="flex items-center justify-end gap-2 px-6 py-4 border-t border-[var(--border-color)]">
<button
type="button"
onClick={onClose}
className="px-4 py-2 text-sm font-medium rounded-md border border-[var(--border-color)]/50 text-[var(--muted)] bg-transparent hover:bg-[var(--background)] hover:text-[var(--foreground)] transition-colors"
>
{t.common?.cancel || 'Cancel'}
</button>
<button
type="button"
onClick={onSubmit}
disabled={isSubmitting}
className="px-4 py-2 text-sm font-medium rounded-md border border-transparent bg-[var(--accent-primary)]/90 text-white hover:bg-[var(--accent-primary)] transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
>
{isSubmitting ? (t.common?.processing || 'Processing...') : (t.common?.generateWiki || 'Generate Wiki')}
</button>
</div>
</div>
</div>
</div>
);
}