Add complete frontend implementation and Docker deployment setup
- Implement React frontend with TypeScript and Tailwind CSS - Add scrappbook.de-inspired UI design with photo galleries - Implement authentication, photo viewing, and download features - Add Docker Swarm configuration with Traefik reverse proxy - Set up Drone CI/CD pipeline for automated deployments - Add monitoring stack with Prometheus and Grafana - Create comprehensive deployment documentation - Add simple local development setup with docker-compose.local.yml Features: - Password-protected galleries with expiration warnings - Responsive photo grid with lightbox viewer - Bulk download functionality - Hot reload development environment - Email testing with Mailhog - Production-ready deployment scripts 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import React from 'react';
|
||||
import { AlertTriangle, Download } from 'lucide-react';
|
||||
import Countdown from 'react-countdown';
|
||||
import { parseISO } from 'date-fns';
|
||||
|
||||
interface ExpirationBannerProps {
|
||||
daysRemaining: number;
|
||||
expiresAt: string;
|
||||
}
|
||||
|
||||
export const ExpirationBanner: React.FC<ExpirationBannerProps> = ({
|
||||
daysRemaining,
|
||||
expiresAt
|
||||
}) => {
|
||||
const expirationDate = parseISO(expiresAt);
|
||||
|
||||
const countdownRenderer = ({ days, hours, minutes, completed }: any) => {
|
||||
if (completed) {
|
||||
return <span>Gallery has expired</span>;
|
||||
} else {
|
||||
return (
|
||||
<span className="font-mono">
|
||||
{days}d {hours}h {minutes}m
|
||||
</span>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const getBannerColor = () => {
|
||||
if (daysRemaining <= 1) return 'bg-red-600';
|
||||
if (daysRemaining <= 3) return 'bg-amber-600';
|
||||
return 'bg-amber-500';
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`${getBannerColor()} text-white sticky top-0 z-50`}>
|
||||
<div className="container py-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<AlertTriangle className="w-5 h-5 mr-2 animate-pulse" />
|
||||
<span className="font-medium">
|
||||
Gallery expires in <Countdown date={expirationDate} renderer={countdownRenderer} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center text-sm">
|
||||
<Download className="w-4 h-4 mr-1" />
|
||||
<span>Download your photos now!</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user