* Add GitLab integration components Introduced PushToGitLabDialog and GitlabConnection components to handle GitLab project connections and push functionality. Includes user authentication, project handling, and UI for seamless integration with GitLab. * Add components for GitLab connection and push dialog Introduce `GitlabConnection` and `PushToGitLabDialog` components to handle GitLab integration. These components allow users to connect their GitLab account, manage recent projects, and push code to a GitLab repository with detailed configurations and feedback. * Fix GitLab personal access tokens link to use correct URL * Update GitHub push call to use new pushToRepository method * Enhance GitLab integration with performance improvements - Add comprehensive caching system for repositories and user data - Implement pagination and search/filter functionality with debouncing - Add skeleton loaders and improved loading states - Implement retry logic for API calls with exponential backoff - Add background refresh capabilities - Improve error handling and user feedback - Optimize API calls to reduce loading times * feat: implement GitLab integration with connection management and repository handling - Add GitLab connection UI components - Implement GitLab API service for repository operations - Add GitLab connection store for state management - Update existing connection components (Vercel, Netlify) - Add repository listing and statistics display - Refactor GitLab components into organized folder structure * fix: resolve GitLab deployment issues and improve user experience - Fix DialogTitle accessibility warnings for screen readers - Remove CORS-problematic attributes from avatar images to prevent loading errors - Enhance GitLab API error handling with detailed error messages - Fix project creation settings to prevent initial commit conflicts - Add automatic GitLab connection state initialization on app startup - Improve deployment dialog UI with better error handling and user feedback - Add GitLab deployment source type to action runner system - Clean up deprecated push dialog files and consolidate deployment components 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: implement GitHub clone repository dialog functionality This commit fixes the missing GitHub repository selection dialog in the "Clone a repo" feature by implementing the same elegant interface pattern used by GitLab. Key Changes: - Added onCloneRepository prop support to GitHubConnection component - Updated RepositoryCard to generate proper GitHub clone URLs (https://github.com/{full_name}.git) - Implemented full GitHub repository selection dialog in GitCloneButton.tsx - Added proper dialog close handling after successful clone operations - Maintained existing GitHub connection settings page functionality Technical Details: - Follows same component patterns as GitLab implementation - Uses proper TypeScript interfaces for clone URL handling - Includes professional dialog styling with loading states - Supports repository search, pagination, and authentication flow The GitHub clone experience now matches GitLab's functionality, providing users with a unified and intuitive repository selection interface across both providers. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Clean up unused connection components - Remove ConnectionForm.tsx (unused GitHub form component) - Remove CreateBranchDialog.tsx (unused branch creation dialog) - Remove RepositoryDialogContext.tsx (unused context provider) - Remove empty components/ directory These files were not referenced anywhere in the codebase and were leftover from development. * Remove environment variables info section from ConnectionsTab - Remove collapsible environment variables section - Clean up unused state and imports - Simplify the connections tab UI * Reorganize connections folder structure - Create netlify/ folder and move NetlifyConnection.tsx - Create vercel/ folder and move VercelConnection.tsx - Add index.ts files for both netlify and vercel folders - Update imports in ConnectionsTab.tsx to use new folder structure - All connection components now follow consistent folder organization --------- Co-authored-by: Hayat Bourgi <hayat.bourgi@montyholding.com> Co-authored-by: Hayat55 <53140162+Hayat55@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
154 lines
6.4 KiB
TypeScript
154 lines
6.4 KiB
TypeScript
import React, { useState } from 'react';
|
|
import * as Dialog from '@radix-ui/react-dialog';
|
|
import { motion } from 'framer-motion';
|
|
import { toast } from 'react-toastify';
|
|
import { Button } from '~/components/ui/Button';
|
|
import { githubConnectionStore } from '~/lib/stores/githubConnection';
|
|
|
|
interface AuthDialogProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
}
|
|
|
|
export function AuthDialog({ isOpen, onClose }: AuthDialogProps) {
|
|
const [token, setToken] = useState('');
|
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
const [tokenType, setTokenType] = useState<'classic' | 'fine-grained'>('classic');
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
|
|
if (!token.trim()) {
|
|
toast.error('Please enter a valid GitHub token');
|
|
return;
|
|
}
|
|
|
|
setIsSubmitting(true);
|
|
|
|
try {
|
|
await githubConnectionStore.connect(token.trim(), tokenType);
|
|
toast.success('Successfully connected to GitHub!');
|
|
onClose();
|
|
setToken('');
|
|
} catch (error) {
|
|
console.error('GitHub connection failed:', error);
|
|
toast.error(`Failed to connect to GitHub: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
} finally {
|
|
setIsSubmitting(false);
|
|
}
|
|
};
|
|
|
|
const handleClose = () => {
|
|
if (!isSubmitting) {
|
|
setToken('');
|
|
onClose();
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Dialog.Root open={isOpen} onOpenChange={handleClose}>
|
|
<Dialog.Portal>
|
|
<Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
|
|
<Dialog.Content asChild>
|
|
<motion.div
|
|
initial={{ opacity: 0, scale: 0.95 }}
|
|
animate={{ opacity: 1, scale: 1 }}
|
|
exit={{ opacity: 0, scale: 0.95 }}
|
|
className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-md bg-bolt-elements-background-depth-1 rounded-lg border border-bolt-elements-borderColor shadow-xl z-50"
|
|
>
|
|
<div className="p-6">
|
|
<Dialog.Title className="text-lg font-semibold text-bolt-elements-textPrimary mb-4">
|
|
Connect to GitHub
|
|
</Dialog.Title>
|
|
|
|
<form onSubmit={handleSubmit} className="space-y-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-bolt-elements-textPrimary mb-2">Token Type</label>
|
|
<div className="flex gap-2">
|
|
<label className="flex items-center">
|
|
<input
|
|
type="radio"
|
|
value="classic"
|
|
checked={tokenType === 'classic'}
|
|
onChange={(e) => setTokenType(e.target.value as 'classic')}
|
|
className="mr-2"
|
|
/>
|
|
<span className="text-sm text-bolt-elements-textSecondary">Classic Token</span>
|
|
</label>
|
|
<label className="flex items-center">
|
|
<input
|
|
type="radio"
|
|
value="fine-grained"
|
|
checked={tokenType === 'fine-grained'}
|
|
onChange={(e) => setTokenType(e.target.value as 'fine-grained')}
|
|
className="mr-2"
|
|
/>
|
|
<span className="text-sm text-bolt-elements-textSecondary">Fine-grained Token</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label htmlFor="token" className="block text-sm font-medium text-bolt-elements-textPrimary mb-2">
|
|
GitHub Personal Access Token
|
|
</label>
|
|
<input
|
|
id="token"
|
|
type="password"
|
|
value={token}
|
|
onChange={(e) => setToken(e.target.value)}
|
|
placeholder="ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
className="w-full px-3 py-2 bg-bolt-elements-background-depth-2 border border-bolt-elements-borderColor rounded-md text-bolt-elements-textPrimary placeholder-bolt-elements-textTertiary focus:outline-none focus:ring-1 focus:ring-bolt-elements-borderColorActive"
|
|
disabled={isSubmitting}
|
|
autoComplete="off"
|
|
/>
|
|
</div>
|
|
|
|
<div className="bg-bolt-elements-background-depth-2 border border-bolt-elements-borderColor rounded-md p-4">
|
|
<div className="flex items-start gap-3">
|
|
<div className="i-ph:info w-5 h-5 text-bolt-elements-icon-info mt-0.5 flex-shrink-0" />
|
|
<div className="text-sm text-bolt-elements-textSecondary space-y-2">
|
|
<p>To create a GitHub Personal Access Token:</p>
|
|
<ol className="list-decimal list-inside space-y-1 text-xs">
|
|
<li>Go to GitHub Settings → Developer settings → Personal access tokens</li>
|
|
<li>Click "Generate new token"</li>
|
|
<li>Select appropriate scopes (repo, user, etc.)</li>
|
|
<li>Copy and paste the token here</li>
|
|
</ol>
|
|
<p className="text-xs">
|
|
<a
|
|
href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="text-bolt-elements-textAccent hover:underline"
|
|
>
|
|
Learn more about creating tokens →
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex gap-3 pt-4">
|
|
<Button
|
|
type="button"
|
|
variant="outline"
|
|
onClick={handleClose}
|
|
disabled={isSubmitting}
|
|
className="flex-1"
|
|
>
|
|
Cancel
|
|
</Button>
|
|
<Button type="submit" disabled={!token.trim() || isSubmitting} className="flex-1">
|
|
{isSubmitting ? 'Connecting...' : 'Connect'}
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</motion.div>
|
|
</Dialog.Content>
|
|
</Dialog.Portal>
|
|
</Dialog.Root>
|
|
);
|
|
}
|