- Created complete project directory structure: - Frontend with Next.js 15.2.3 app router structure - Backend with Express API endpoints - Docker configurations with security best practices - MongoDB initialization with schema validation - Nginx configuration with security headers - Implemented core file templates: - Custom video player with transcript display options - MongoDB schemas with validation for Videos and Members - JWT authentication middleware with role-based access control - Docker Compose with resource limits and security - Frontend/backend package.json with dependencies - Updated documentation: - Enhanced TECH_STACK with latest version details - Updated TO_DO.txt with WCAG 2.2 AA requirements - Updated planned_implementation.txt with current best practices - Refreshed all Memory Bank files with current state - Security and accessibility improvements: - Added MongoDB 7.0 schema validation with - Enhanced video requirements with mandatory transcripts and thumbnails - Updated accessibility to WCAG 2.2 AA standards - Added security best practices for Docker deployments
111 lines
2.4 KiB
TypeScript
111 lines
2.4 KiB
TypeScript
'use client';
|
|
|
|
import React from 'react';
|
|
|
|
interface IconProps {
|
|
className?: string;
|
|
size?: number;
|
|
color?: string;
|
|
}
|
|
|
|
export const PlayIcon: React.FC<IconProps> = ({
|
|
className = '',
|
|
size = 24,
|
|
color = 'currentColor'
|
|
}) => {
|
|
return (
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width={size}
|
|
height={size}
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke={color}
|
|
className={`icon play-icon ${className}`}
|
|
aria-hidden="true"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
>
|
|
<polygon points="5 3 19 12 5 21 5 3" />
|
|
</svg>
|
|
);
|
|
};
|
|
|
|
export const PauseIcon: React.FC<IconProps> = ({
|
|
className = '',
|
|
size = 24,
|
|
color = 'currentColor'
|
|
}) => {
|
|
return (
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width={size}
|
|
height={size}
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke={color}
|
|
className={`icon pause-icon ${className}`}
|
|
aria-hidden="true"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
>
|
|
<rect x="6" y="4" width="4" height="16" />
|
|
<rect x="14" y="4" width="4" height="16" />
|
|
</svg>
|
|
);
|
|
};
|
|
|
|
export const FullscreenIcon: React.FC<IconProps> = ({
|
|
className = '',
|
|
size = 24,
|
|
color = 'currentColor'
|
|
}) => {
|
|
return (
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width={size}
|
|
height={size}
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke={color}
|
|
className={`icon fullscreen-icon ${className}`}
|
|
aria-hidden="true"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
>
|
|
<path d="M8 3H5a2 2 0 0 0-2 2v3" />
|
|
<path d="M21 8V5a2 2 0 0 0-2-2h-3" />
|
|
<path d="M3 16v3a2 2 0 0 0 2 2h3" />
|
|
<path d="M16 21h3a2 2 0 0 0 2-2v-3" />
|
|
</svg>
|
|
);
|
|
};
|
|
|
|
export const VolumeIcon: React.FC<IconProps> = ({
|
|
className = '',
|
|
size = 24,
|
|
color = 'currentColor'
|
|
}) => {
|
|
return (
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width={size}
|
|
height={size}
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke={color}
|
|
className={`icon volume-icon ${className}`}
|
|
aria-hidden="true"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
>
|
|
<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" />
|
|
<path d="M15 8a5 5 0 0 1 0 8" />
|
|
<path d="M19 5a9 9 0 0 1 0 14" />
|
|
</svg>
|
|
);
|
|
};
|