UNPKG

leumas-private-shared

Version:

Private React JSX Package For Leumas Shared Components, Headers, Footers, Asides, Login Pages, API Key Manager and much more. Styles and everything reusable to avoid DRY code across all of our subdomains

133 lines (121 loc) 4.82 kB
import React, { useState } from 'react'; import { Container, Grid, Card, CardContent, CardMedia, Typography, Button, Box, Tabs, Tab, Pagination } from '@mui/material'; const Gallery = ({ images, frequencyData, audioPlaying, strobeMode }) => { const [activeCategory, setActiveCategory] = useState('All'); const [currentPage, setCurrentPage] = useState(1); const itemsPerPage = 12; // Derive categories from images const categories = ['All', ...new Set(images.map(image => image.category))]; // Filter images based on the active category const filteredImages = images.filter(image => activeCategory === 'All' || image.category === activeCategory ); // Paginate images const paginatedImages = filteredImages.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage); const handleCategoryChange = (event, newValue) => { setActiveCategory(newValue); setCurrentPage(1); // Reset to the first page when the category changes }; const handlePageChange = (event, value) => { setCurrentPage(value); }; // Function to get the border style based on the frequency data const getBorderStyle = (index) => { if (audioPlaying && frequencyData && frequencyData.length > 0) { const colorIndex = index % frequencyData.length; const intensity = frequencyData[colorIndex]; const getColor = () => { if (strobeMode) { const randomColor = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`; return randomColor; } return `rgba(0, 0, 255, ${intensity / 255})`; }; return { borderImage: `linear-gradient(45deg, ${getColor()}, ${getColor()}) 1`, animation: 'wave 1s infinite', boxShadow: `0 0 ${intensity / 5}px ${getColor()}` }; } return { border: '3px solid transparent' }; }; return ( <Container sx={{ py: 4 }}> <Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 4 }}> <Tabs value={activeCategory} onChange={handleCategoryChange} variant="scrollable" scrollButtons="auto" aria-label="gallery categories" > {categories.map((category, index) => ( <Tab key={index} label={category} value={category} /> ))} </Tabs> </Box> <Grid container spacing={2}> {paginatedImages.map((image, index) => ( <Grid item key={index} xs={12} sm={6} md={4}> <Card sx={{ cursor: 'pointer', display: 'flex', flexDirection: 'column', borderRadius: '8px', transition: 'transform 0.3s, box-shadow 0.3s, border-color 0.5s ease, border-width 0.5s ease', ':hover': { transform: 'scale(1.05)', boxShadow: '0 8px 16px rgba(0, 0, 0, 0.3)' }, ...getBorderStyle(index), '@keyframes wave': { '0%': { borderImage: `linear-gradient(45deg, rgba(0, 0, 255, 0.1), rgba(0, 0, 128, 0.1)) 1` }, '50%': { borderImage: `linear-gradient(45deg, rgba(0, 0, 255, 1), rgba(0, 0, 128, 1)) 1` }, '100%': { borderImage: `linear-gradient(45deg, rgba(0, 0, 255, 0.1), rgba(0, 0, 128, 0.1)) 1` }, } }} > <CardMedia component="img" sx={{ pt: 0, // Ensure the image starts at the top height: '180px' // Set a fixed height for the images }} image={image.src} alt={image.title} /> <CardContent sx={{ flexGrow: 1 }}> <Typography gutterBottom variant="h5" component="h2"> {image.title.substring(0,22)}... </Typography> </CardContent> <Box sx={{ p: 2, textAlign: 'center' }}> <Button variant="contained" color="primary" href={image.link} target="_blank" rel="noopener noreferrer" > Learn More </Button> </Box> </Card> </Grid> ))} </Grid> <Box sx={{ display: 'flex', justifyContent: 'center', mt: 4 }}> <Pagination count={Math.ceil(filteredImages.length / itemsPerPage)} page={currentPage} onChange={handlePageChange} color="primary" /> </Box> </Container> ); }; export default Gallery;