Initial commit: CHORUS Services marketing website
Complete Next.js website with Docker containerization: - Next.js 14 with TypeScript and Tailwind CSS - Responsive design with modern UI components - Hero section, features showcase, testimonials - FAQ section with comprehensive content - Contact forms and newsletter signup - Docker production build with Nginx - Health checks and monitoring support - SEO optimization and performance tuning Ready for integration as git submodule in main CHORUS project. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
69
components/ui/Loading.tsx
Normal file
69
components/ui/Loading.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Spin, Typography } from 'antd';
|
||||
import { cn } from '@/utils/cn';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
interface LoadingProps {
|
||||
size?: 'small' | 'default' | 'large';
|
||||
text?: string;
|
||||
fullScreen?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const Loading: React.FC<LoadingProps> = ({
|
||||
size = 'default',
|
||||
text = 'Loading...',
|
||||
fullScreen = false,
|
||||
className,
|
||||
}) => {
|
||||
const containerClasses = cn(
|
||||
'flex flex-col items-center justify-center',
|
||||
fullScreen ? 'fixed inset-0 bg-chorus-charcoal z-50' : 'py-8',
|
||||
className
|
||||
);
|
||||
|
||||
const spinnerSize = size === 'small' ? 20 : size === 'large' ? 40 : 30;
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className={containerClasses}
|
||||
>
|
||||
<motion.div
|
||||
animate={{ rotate: 360 }}
|
||||
transition={{
|
||||
duration: 1,
|
||||
repeat: Infinity,
|
||||
ease: 'linear',
|
||||
}}
|
||||
className="mb-4"
|
||||
>
|
||||
<div
|
||||
className="rounded-full border-4 border-chorus-blue/20 border-t-chorus-blue"
|
||||
style={{
|
||||
width: spinnerSize,
|
||||
height: spinnerSize,
|
||||
}}
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
{text && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 0.2 }}
|
||||
>
|
||||
<Text className="text-gray-300 text-sm">{text}</Text>
|
||||
</motion.div>
|
||||
)}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Loading;
|
||||
Reference in New Issue
Block a user