feat: github fix and ui improvements (#1685)
* feat: Add reusable UI components and fix GitHub repository display * style: Fix linting issues in UI components * fix: Add close icon to GitHub Connection Required dialog * fix: Add CloseButton component to fix white background issue in dialog close icons * Fix close button styling in dialog components to address ghost white issue in dark mode * fix: update icon color to tertiary for consistency The icon color was changed from `text-bolt-elements-icon-info` to `text-bolt-elements-icon-tertiary` * fix: improve repository selection dialog tab styling for dark mode - Update tab menu styling to prevent white background in dark mode - Use explicit color values for better dark/light mode compatibility - Improve hover and active states for better visual hierarchy - Remove unused Tabs imports --------- Co-authored-by: KevIsDev <zennerd404@gmail.com>
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import type { GitHubRepoInfo } from '~/types/GitHub';
|
||||
|
||||
interface RepositoryCardProps {
|
||||
repo: GitHubRepoInfo;
|
||||
onSelect: () => void;
|
||||
}
|
||||
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export function RepositoryCard({ repo, onSelect }: RepositoryCardProps) {
|
||||
// Use a consistent styling for all repository cards
|
||||
const getCardStyle = () => {
|
||||
return 'from-bolt-elements-background-depth-1 to-bolt-elements-background-depth-1 dark:from-bolt-elements-background-depth-2-dark dark:to-bolt-elements-background-depth-2-dark';
|
||||
};
|
||||
|
||||
// Format the date in a more readable format
|
||||
const formatDate = (dateString: string) => {
|
||||
const date = new Date(dateString);
|
||||
const now = new Date();
|
||||
const diffTime = Math.abs(now.getTime() - date.getTime());
|
||||
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
||||
|
||||
if (diffDays <= 1) {
|
||||
return 'Today';
|
||||
}
|
||||
|
||||
if (diffDays <= 2) {
|
||||
return 'Yesterday';
|
||||
}
|
||||
|
||||
if (diffDays <= 7) {
|
||||
return `${diffDays} days ago`;
|
||||
}
|
||||
|
||||
if (diffDays <= 30) {
|
||||
return `${Math.floor(diffDays / 7)} weeks ago`;
|
||||
}
|
||||
|
||||
return date.toLocaleDateString(undefined, {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
});
|
||||
};
|
||||
|
||||
const cardStyle = useMemo(() => getCardStyle(), []);
|
||||
|
||||
// const formattedDate = useMemo(() => formatDate(repo.updated_at), [repo.updated_at]);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
className={`p-5 rounded-xl bg-gradient-to-br ${cardStyle} border border-bolt-elements-borderColor dark:border-bolt-elements-borderColor-dark hover:border-purple-500/40 transition-all duration-300 shadow-sm hover:shadow-md`}
|
||||
whileHover={{
|
||||
scale: 1.02,
|
||||
y: -2,
|
||||
transition: { type: 'spring', stiffness: 400, damping: 17 },
|
||||
}}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<div className="flex items-start justify-between mb-3 gap-3">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="w-10 h-10 rounded-xl bg-bolt-elements-background-depth-1/80 dark:bg-bolt-elements-background-depth-4/80 backdrop-blur-sm flex items-center justify-center text-purple-500 shadow-sm">
|
||||
<span className="i-ph:git-branch w-5 h-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-medium text-bolt-elements-textPrimary dark:text-bolt-elements-textPrimary-dark text-base">
|
||||
{repo.name}
|
||||
</h3>
|
||||
<p className="text-xs text-bolt-elements-textTertiary dark:text-bolt-elements-textTertiary-dark flex items-center gap-1">
|
||||
<span className="i-ph:user w-3 h-3" />
|
||||
{repo.full_name.split('/')[0]}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<motion.button
|
||||
onClick={onSelect}
|
||||
className="px-4 py-2 h-9 rounded-lg bg-purple-500 text-white hover:bg-purple-600 transition-all duration-200 flex items-center gap-2 min-w-[100px] justify-center text-sm shadow-sm hover:shadow-md"
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
<span className="i-ph:git-pull-request w-3.5 h-3.5" />
|
||||
Import
|
||||
</motion.button>
|
||||
</div>
|
||||
|
||||
{repo.description && (
|
||||
<div className="mb-4 bg-bolt-elements-background-depth-1/50 dark:bg-bolt-elements-background-depth-4/50 backdrop-blur-sm p-3 rounded-lg border border-bolt-elements-borderColor/30 dark:border-bolt-elements-borderColor-dark/30">
|
||||
<p className="text-sm text-bolt-elements-textSecondary dark:text-bolt-elements-textSecondary-dark line-clamp-2">
|
||||
{repo.description}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
{repo.private && (
|
||||
<span className="flex items-center gap-1 px-2 py-1 rounded-lg bg-purple-500/10 text-purple-600 dark:text-purple-400 text-xs">
|
||||
<span className="i-ph:lock w-3 h-3" />
|
||||
Private
|
||||
</span>
|
||||
)}
|
||||
{repo.language && (
|
||||
<span className="flex items-center gap-1 px-2 py-1 rounded-lg bg-bolt-elements-background-depth-1/50 dark:bg-bolt-elements-background-depth-4/50 backdrop-blur-sm text-bolt-elements-textSecondary dark:text-bolt-elements-textSecondary-dark text-xs border border-bolt-elements-borderColor/30 dark:border-bolt-elements-borderColor-dark/30">
|
||||
<span className="i-ph:code w-3 h-3" />
|
||||
{repo.language}
|
||||
</span>
|
||||
)}
|
||||
<span className="flex items-center gap-1 px-2 py-1 rounded-lg bg-bolt-elements-background-depth-1/50 dark:bg-bolt-elements-background-depth-4/50 backdrop-blur-sm text-bolt-elements-textSecondary dark:text-bolt-elements-textSecondary-dark text-xs border border-bolt-elements-borderColor/30 dark:border-bolt-elements-borderColor-dark/30">
|
||||
<span className="i-ph:star w-3 h-3" />
|
||||
{repo.stargazers_count.toLocaleString()}
|
||||
</span>
|
||||
{repo.forks_count > 0 && (
|
||||
<span className="flex items-center gap-1 px-2 py-1 rounded-lg bg-bolt-elements-background-depth-1/50 dark:bg-bolt-elements-background-depth-4/50 backdrop-blur-sm text-bolt-elements-textSecondary dark:text-bolt-elements-textSecondary-dark text-xs border border-bolt-elements-borderColor/30 dark:border-bolt-elements-borderColor-dark/30">
|
||||
<span className="i-ph:git-fork w-3 h-3" />
|
||||
{repo.forks_count.toLocaleString()}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mt-3 pt-3 border-t border-bolt-elements-borderColor/30 dark:border-bolt-elements-borderColor-dark/30 flex items-center justify-between">
|
||||
<span className="flex items-center gap-1 text-xs text-bolt-elements-textTertiary dark:text-bolt-elements-textTertiary-dark">
|
||||
<span className="i-ph:clock w-3 h-3" />
|
||||
Updated {formatDate(repo.updated_at)}
|
||||
</span>
|
||||
|
||||
{repo.topics && repo.topics.length > 0 && (
|
||||
<span className="text-xs text-bolt-elements-textTertiary dark:text-bolt-elements-textTertiary-dark">
|
||||
{repo.topics.slice(0, 1).map((topic) => (
|
||||
<span
|
||||
key={topic}
|
||||
className="px-1.5 py-0.5 rounded-full bg-bolt-elements-background-depth-1/50 dark:bg-bolt-elements-background-depth-4/50 text-xs"
|
||||
>
|
||||
{topic}
|
||||
</span>
|
||||
))}
|
||||
{repo.topics.length > 1 && <span className="ml-1">+{repo.topics.length - 1}</span>}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user