copied lab7

This commit is contained in:
2026-04-16 20:07:10 +10:00
parent 48fae5325b
commit 4f8f033306
42 changed files with 6232 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
import Card from '@mui/material/Card';
import CardContent from '@mui/material/CardContent';
import CardMedia from '@mui/material/CardMedia';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import { styled } from '@mui/material/styles';
import buildings from '../data.tsx';
import { useParams, Link } from 'react-router-dom';
const StyledTypography = styled(Typography)(({ theme }) => ({
color: theme.palette.text.secondary,
textAlign: 'justify',
marginBottom: '1em',
}));
function Building() {
const { id } = useParams();
const building = buildings[Number(id)];
return (
<>
<Card sx={{ display: 'flex', flexDirection: "column", alignItems: "center" }} >
<Box sx={{ display: 'flex', flexDirection: 'row', alignSelf: 'flex-start', gap: '0.5em', m: '1em' }}>
<Link to="/" style={{ textDecoration: 'none' }}><Typography sx={{color:"#659adf"}}>ГЛАВНАЯ</Typography></Link> &gt; {building.title}
</Box>
<Typography gutterBottom variant="h5" >
{building.title}
</Typography>
<CardMedia
component="img"
alt={building.title}
image={building.img}
sx={{ width:"auto", maxHeight:"45vh", rounded: '8px' }}
/>
<Box>
<CardContent>
<Box sx={{ display: 'flex', flexDirection: { xs: 'column', sm: 'row' }, gap: {xs:0, sm:'2em'}}}>
{building.description.map((item, ind) => (
<StyledTypography key={ind} variant="body2" sx={{ flex: 1 }}>
{item}
</StyledTypography>
))}
</Box>
</CardContent>
</Box>
</Card>
</>
)
}
export default Building;

View File

@@ -0,0 +1,51 @@
import Navbar from "../components/Navbar";
import CustomFooter from "../components/CustomFooter";
import Select from '@mui/material/Select';
import type { SelectChangeEvent } from '@mui/material/Select';
import Box from '@mui/material/Box';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import FormControl from '@mui/material/FormControl';
import * as React from 'react';
import {years, countries, types } from "./groupdata";
import GroupGrid from "./components/GroupGrid";
import GroupChart from "./components/GroupChart";
type tSelect = "Страна" | "Год" | "Тип";
function Chart() {
const [group, setGroup] = React.useState<tSelect>("Страна");
const [groupData, setGroupData] = React.useState(countries);
const handleChange = (event: SelectChangeEvent) => {
setGroup(event.target.value as tSelect);
setGroupData([countries, years, types][["Страна", "Год", "Тип"].indexOf(event.target.value)]);
}
return (
<>
<Navbar active="3" />
<Box sx={{ width: "200px", m: "auto" }}>
<FormControl fullWidth>
<InputLabel> Группировать по </InputLabel>
<Select
id="select-group"
value={group}
label="Группировать по"
onChange={handleChange}
>
<MenuItem value="Страна"> Стране </MenuItem>
<MenuItem value="Год"> Году </MenuItem>
<MenuItem value="Тип"> Типу </MenuItem>
</Select>
</FormControl>
</Box>
<GroupChart data={groupData} />
<GroupGrid data={groupData} />
<CustomFooter />
</>
);
}
export default Chart;

View File

@@ -0,0 +1,62 @@
import { BarChart } from '@mui/x-charts/BarChart';
import { LineChart } from '@mui/x-charts/LineChart';
import Container from '@mui/material/Container';
import type { tGroup } from "../groupdata";
import { useState } from 'react';
import SettingChart from "./SettingChart";
type GroupProps = {
data: tGroup;
};
function GroupChart({ data }: GroupProps) {
const [isBar, setIsBar] = useState(true);
const [series, setSeries] = useState({
'Максимальная высота': true,
'Средняя высота': false,
'Минимальная высота': false,
});
const selectedSeries = Object.entries(series).filter(item => item[1] === true);
let seriesY = selectedSeries.map(item => {
return {
dataKey: item[0],
label: item[0],
barLabel: selectedSeries.length === 1 ? ('value' as const) : undefined,
}
});
const chartSetting = {
yAxis: [{ label: 'Высота (м)' }],
height: 400,
};
return (
<Container maxWidth="lg">
{isBar && <BarChart
dataset={data}
xAxis={[{ scaleType: 'band', dataKey: 'Группа' }]}
series={seriesY}
slotProps={{
legend: {
position: { vertical: 'bottom', horizontal: 'center' },
}
}}
{...chartSetting}
/>}
{!isBar &&<LineChart
dataset={data}
xAxis={[{ scaleType: 'band', dataKey: 'Группа' }]}
series={seriesY}
slotProps={{
legend: {
position: { vertical: 'bottom', horizontal: 'center' },
},
}}
{...chartSetting}
/>}
<SettingChart series={series} setSeries={setSeries} isBar={isBar} setIsBar={setIsBar} />
</Container>
)
};
export default GroupChart;

View File

@@ -0,0 +1,30 @@
import { DataGrid } from "@mui/x-data-grid";
import type { GridRowsProp, GridColDef } from "@mui/x-data-grid";
import Container from '@mui/material/Container';
import { ruRU } from '@mui/x-data-grid/locales';
import type { tGroup } from "../groupdata";
type GroupProps = {
data: tGroup;
};
function GroupGrid({ data }: GroupProps) {
const rows: GridRowsProp = data;
const columns: GridColDef[] = [
{ field: 'Группа', headerName: 'Группа', flex: 1},
{ field: 'Минимальная высота', flex: 0.5},
{ field: 'Максимальная высота', flex: 0.5},
{ field: 'Средняя высота', flex: 0.5},
]
return (
<Container maxWidth="lg" sx={{height: '700px', mt: '20px'}}>
<DataGrid
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
rows={rows}
columns={columns}
/>
</Container>
)
}
export default GroupGrid;

View File

@@ -0,0 +1,95 @@
import FormControl from '@mui/material/FormControl';
import FormLabel from '@mui/material/FormLabel';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import Stack from '@mui/material/Stack';
import Divider from '@mui/material/Divider';
import RadioGroup from '@mui/material/RadioGroup';
import Radio from '@mui/material/Radio';
import Container from '@mui/material/Container';
type tSeries = {
'Максимальная высота': boolean,
'Средняя высота': boolean,
'Минимальная высота': boolean,
}
type CheckboxProps = {
series: tSeries;
setSeries: React.Dispatch<React.SetStateAction<tSeries>>;
isBar: boolean;
setIsBar: React.Dispatch<React.SetStateAction<boolean>>
};
function SettingChart({ series, setSeries, isBar, setIsBar }: CheckboxProps) {
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSeries({
...series,
[event.target.name]: event.target.checked,
});
};
const handleRadioButtonChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setIsBar(event.target.value === "bar");
};
return (
<Stack
direction="row"
divider={<Divider orientation="vertical" flexItem />}
spacing={2}
sx={{ m: "20px 0", justifyContent: "center", }}
>
<FormControl>
<FormLabel id="label-radio-group">
Тип диаграммы:
</FormLabel>
<RadioGroup
name="group-radio"
value={(isBar) ? "bar" : "dot"}
>
<FormControlLabel value="bar"
control={
<Radio checked={isBar} onChange={handleRadioButtonChange} />
}
label="Гистограмма"
/>
<FormControlLabel value="dot"
control={
<Radio checked={!isBar} onChange={handleRadioButtonChange} />
}
label="Линейная"
/>
</RadioGroup>
</FormControl>
<FormControl>
<FormLabel id="label-checkbox-group">
На диаграмме показать:
</FormLabel>
<FormControlLabel
control={
<Checkbox checked={series["Максимальная высота"]}
onChange={handleChange}
name="Максимальная высота" />
}
label="максимальную высоту"
/>
<FormControlLabel
control={
<Checkbox checked={series["Средняя высота"]}
onChange={handleChange}
name="Средняя высота" />
}
label="среднюю высоту"
/>
<FormControlLabel
control={
<Checkbox checked={series["Минимальная высота"]}
onChange={handleChange}
name="Минимальная высота" />
}
label="минимальную высоту"
/>
</FormControl>
</Stack>
)
}
export default SettingChart;

View File

@@ -0,0 +1,87 @@
export type tGroup = {
"id": number,
"Группа": string | number,
"Минимальная высота": number ,
"Максимальная высота": number ,
"Средняя высота": number,
}[];
export const countries: tGroup = [
{ "id": 1, "Группа": "Вьетнам" , "Минимальная высота": 461 , "Максимальная высота": 461 , "Средняя высота": 461 },
{ "id": 2, "Группа": "Германия" , "Минимальная высота": 368 , "Максимальная высота": 368 , "Средняя высота": 368 },
{ "id": 3, "Группа": "Гонконг" , "Минимальная высота": 367 , "Максимальная высота": 484 , "Средняя высота": 410 },
{ "id": 4, "Группа": "Испания" , "Минимальная высота": 356 , "Максимальная высота": 356 , "Средняя высота": 356 },
{ "id": 5, "Группа": "Иран" , "Минимальная высота": 435 , "Максимальная высота": 435 , "Средняя высота": 435 },
{ "id": 6, "Группа": "Казахстан" , "Минимальная высота": 372 , "Максимальная высота": 420 , "Средняя высота": 391 },
{ "id": 7, "Группа": "Канада" , "Минимальная высота": 355 , "Максимальная высота": 553 , "Средняя высота": 429 },
{ "id": 8, "Группа": "КНР" , "Минимальная высота": 356 , "Максимальная высота": 632 , "Средняя высота": 464 },
{ "id": 9, "Группа": "Кувейт" , "Минимальная высота": 372 , "Максимальная высота": 412 , "Средняя высота": 392 },
{ "id": 10, "Группа": "Латвия" , "Минимальная высота": 369 , "Максимальная высота": 369 , "Средняя высота": 369 },
{ "id": 11, "Группа": "Малайзия" , "Минимальная высота": 421 , "Максимальная высота": 452 , "Средняя высота": 437 },
{ "id": 12, "Группа": "ОАЭ" , "Минимальная высота": 355 , "Максимальная высота": 828 , "Средняя высота": 461 },
{ "id": 13, "Группа": "Польша" , "Минимальная высота": 646 , "Максимальная высота": 646 , "Средняя высота": 646 },
{ "id": 14, "Группа": "Россия" , "Минимальная высота": 354 , "Максимальная высота": 540 , "Средняя высота": 420 },
{ "id": 15, "Группа": "Румыния" , "Минимальная высота": 352 , "Максимальная высота": 352 , "Средняя высота": 352 },
{ "id": 16, "Группа": "Словения" , "Минимальная высота": 360 , "Максимальная высота": 360 , "Средняя высота": 360 },
{ "id": 17, "Группа": "США" , "Минимальная высота": 350 , "Максимальная высота": 629 , "Средняя высота": 437 },
{ "id": 18, "Группа": "Тайвань" , "Минимальная высота": 378 , "Максимальная высота": 509 , "Средняя высота": 444 },
{ "id": 19, "Группа": "Узбекистан" , "Минимальная высота": 350 , "Максимальная высота": 375 , "Средняя высота": 363 },
{ "id": 20, "Группа": "Украина" , "Минимальная высота": 354 , "Максимальная высота": 385 , "Средняя высота": 370 },
{ "id": 21, "Группа": "Южная Корея" , "Минимальная высота": 555 , "Максимальная высота": 555 , "Средняя высота": 555 },
{ "id": 22, "Группа": "Япония" , "Минимальная высота": 634 , "Максимальная высота": 634 , "Средняя высота": 634 },
];
export const years: tGroup = [
{ "id": 1 , "Группа": 1931 , "Максимальная высота": 449 , "Минимальная высота": 449 , "Средняя высота": 449 },
{ "id": 2 , "Группа": 1961 , "Максимальная высота": 354 , "Минимальная высота": 354 , "Средняя высота": 354 },
{ "id": 3 , "Группа": 1963 , "Максимальная высота": 629 , "Минимальная высота": 629 , "Средняя высота": 629 },
{ "id": 4 , "Группа": 1967 , "Максимальная высота": 540 , "Минимальная высота": 540 , "Средняя высота": 540 },
{ "id": 5 , "Группа": 1968 , "Максимальная высота": 368 , "Минимальная высота": 368 , "Средняя высота": 368 },
{ "id": 6 , "Группа": 1969 , "Максимальная высота": 457 , "Минимальная высота": 368 , "Средняя высота": 413 },
{ "id": 7 , "Группа": 1971 , "Максимальная высота": 380 , "Минимальная высота": 380 , "Средняя высота": 380 },
{ "id": 8 , "Группа": 1973 , "Максимальная высота": 385 , "Минимальная высота": 385 , "Средняя высота": 385 },
{ "id": 9 , "Группа": 1974 , "Максимальная высота": 646 , "Минимальная высота": 356 , "Средняя высота": 510 },
{ "id": 10 , "Группа": 1976 , "Максимальная высота": 553 , "Минимальная высота": 355 , "Средняя высота": 423 },
{ "id": 11 , "Группа": 1977 , "Максимальная высота": 371 , "Минимальная высота": 371 , "Средняя высота": 371 },
{ "id": 12 , "Группа": 1980 , "Максимальная высота": 350 , "Минимальная высота": 350 , "Средняя высота": 350 },
{ "id": 13 , "Группа": 1983 , "Максимальная высота": 372 , "Минимальная высота": 372 , "Средняя высота": 372 },
{ "id": 14 , "Группа": 1985 , "Максимальная высота": 375 , "Минимальная высота": 370 , "Средняя высота": 373 },
{ "id": 15 , "Группа": 1987 , "Максимальная высота": 420 , "Минимальная высота": 369 , "Средняя высота": 395 },
{ "id": 16 , "Группа": 1990 , "Максимальная высота": 367 , "Минимальная высота": 367 , "Средняя высота": 367 },
{ "id": 17 , "Группа": 1991 , "Максимальная высота": 415 , "Минимальная высота": 415 , "Средняя высота": 415 },
{ "id": 18 , "Группа": 1992 , "Максимальная высота": 405 , "Минимальная высота": 374 , "Средняя высота": 390 },
{ "id": 19 , "Группа": 1994 , "Максимальная высота": 468 , "Минимальная высота": 468 , "Средняя высота": 468 },
{ "id": 20 , "Группа": 1995 , "Максимальная высота": 421 , "Минимальная высота": 352 , "Средняя высота": 387 },
{ "id": 21 , "Группа": 1996 , "Максимальная высота": 384 , "Минимальная высота": 350 , "Средняя высота": 369 },
{ "id": 22 , "Группа": 1997 , "Максимальная высота": 391 , "Минимальная высота": 378 , "Средняя высота": 385 },
{ "id": 23 , "Группа": 1998 , "Максимальная высота": 452 , "Минимальная высота": 452 , "Средняя высота": 452 },
{ "id": 24 , "Группа": 1999 , "Максимальная высота": 421 , "Минимальная высота": 421 , "Средняя высота": 421 },
{ "id": 25 , "Группа": 2000 , "Максимальная высота": 356 , "Минимальная высота": 355 , "Средняя высота": 356 },
{ "id": 26 , "Группа": 2003 , "Максимальная высота": 435 , "Минимальная высота": 416 , "Средняя высота": 426 },
{ "id": 27 , "Группа": 2004 , "Максимальная высота": 509 , "Минимальная высота": 509 , "Средняя высота": 509 },
{ "id": 28 , "Группа": 2008 , "Максимальная высота": 492 , "Минимальная высота": 363 , "Средняя высота": 407 },
{ "id": 29 , "Группа": 2009 , "Максимальная высота": 600 , "Минимальная высота": 423 , "Средняя высота": 489 },
{ "id": 30 , "Группа": 2010 , "Максимальная высота": 828 , "Минимальная высота": 376 , "Средняя высота": 514 },
{ "id": 31 , "Группа": 2011 , "Максимальная высота": 440 , "Минимальная высота": 440 , "Средняя высота": 440 },
{ "id": 32 , "Группа": 2012 , "Максимальная высота": 634 , "Минимальная высота": 634 , "Средняя высота": 634 },
{ "id": 33 , "Группа": 2013 , "Максимальная высота": 632 , "Минимальная высота": 632 , "Средняя высота": 632 },
{ "id": 34 , "Группа": 2014 , "Максимальная высота": 381 , "Минимальная высота": 381 , "Средняя высота": 381 },
{ "id": 35 , "Группа": 2015 , "Максимальная высота": 426 , "Минимальная высота": 354 , "Средняя высота": 387 },
{ "id": 36 , "Группа": 2016 , "Максимальная высота": 374 , "Минимальная высота": 374 , "Средняя высота": 374 },
{ "id": 37 , "Группа": 2017 , "Максимальная высота": 600 , "Минимальная высота": 555 , "Средняя высота": 578 },
{ "id": 38 , "Группа": 2018 , "Максимальная высота": 462 , "Минимальная высота": 461 , "Средняя высота": 462 },
];
export const types: tGroup = [
{ "id": 1 , "Группа": "Антенная мачта" , "Максимальная высота": 646 , "Минимальная высота": 646 , "Средняя высота": 646 },
{ "id": 2 , "Группа": "Башня" , "Максимальная высота": 375 , "Минимальная высота": 372 , "Средняя высота": 374 },
{ "id": 3 , "Группа": "Бетонная башня" , "Максимальная высота": 634 , "Минимальная высота": 350 , "Средняя высота": 444 },
{ "id": 4 , "Группа": "Гиперболоидная башня" , "Максимальная высота": 600 , "Минимальная высота": 600 , "Средняя высота": 600 },
{ "id": 5 , "Группа": "Дымовая труба" , "Максимальная высота": 420 , "Минимальная высота": 350 , "Средняя высота": 370 },
{ "id": 6 , "Группа": "Небоскрёб" , "Максимальная высота": 828 , "Минимальная высота": 354 , "Средняя высота": 441 },
{ "id": 7 , "Группа": "Радиомачта" , "Максимальная высота": 629 , "Минимальная высота": 354 , "Средняя высота": 492 },
{ "id": 8 , "Группа": "Решётчатая мачта" , "Максимальная высота": 385 , "Минимальная высота": 385 , "Средняя высота": 385 },
];

View File

@@ -0,0 +1,26 @@
import Container from '@mui/material/Container';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import { styled } from '@mui/material/styles';
const StyledContainer = styled(Container)(({ theme }) => ({
backgroundColor: theme.palette.action.hover,
borderRadius: `calc(${theme.shape.borderRadius}px + 8px)`,
marginTop: "50px",
padding: "20px",
color: theme.palette.text.secondary
}));
function CustomFooter() {
return (
<StyledContainer >
<Grid style={{ justifyContent: "space-around",}} container>
<Typography> OkunElya</Typography>
<Typography> 2026</Typography>
<Typography> FEFU</Typography>
</Grid>
</StyledContainer>
);
}
export default CustomFooter;

View File

@@ -0,0 +1,119 @@
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import { styled } from '@mui/material/styles';
import Container from '@mui/material/Container';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import IconButton from '@mui/material/IconButton';
import CloseRoundedIcon from '@mui/icons-material/CloseRounded';
import MenuItem from '@mui/material/MenuItem';
import Drawer from '@mui/material/Drawer';
import MenuIcon from '@mui/icons-material/Menu';
import MenuList from '@mui/material/MenuList';
import { Link } from 'react-router-dom';
import { useState } from 'react';
const StyledToolbar = styled(Toolbar)(({ theme }) => ({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
flexShrink: 0,
borderRadius: `calc(${theme.shape.borderRadius}px + 8px)`,
border: '1px solid',
borderColor: theme.palette.divider,
padding: '8px 12px',
}));
const StyledMenuItem = styled(MenuItem)(({ }) => ({
'&.Mui-selected': {
backgroundColor: '#1976d2',
color: "white",
},
'&.Mui-selected:hover': {
backgroundColor: '#11579c',
color: "white",
},
'&:hover': {
backgroundColor: 'rgba(69, 146, 223, 0.45)',
},
}));
interface ComponentProps {
active: string;
}
function NavBar({ active }: ComponentProps) {
const [open, setOpen] = useState(false);
const toggleDrawer = (newOpen: boolean) => () => {
setOpen(newOpen);
};
return (
<AppBar
position="static"
sx={{
boxShadow: 0,
bgcolor: 'transparent',
mt: '28px',
}}
>
<Container maxWidth="xl">
<StyledToolbar>
<Typography variant="h6" sx={{ color: '#5d8aa8' }}>
Самые высокие здания и сооружения
</Typography>
<Box sx={{ display: { xs: 'none', md: 'flex' } }}>
<Link to="/">
<Button variant={active == '1' ? 'contained' : 'text'} color="info" size="medium">
Главная
</Button>
</Link>
<Link to="/list">
<Button variant={active == '2' ? 'contained' : 'text'} color="info" size="medium">
Список зданий
</Button>
</Link>
<Link to="/chart">
<Button variant={active == '3' ? 'contained' : 'text'} color="info" size="medium">
Контакты
</Button>
</Link>
</Box>
<Box sx={{ display: { xs: 'flex', md: 'none' } }}>
<IconButton aria-label="Menu button" onClick={toggleDrawer(true)}>
<MenuIcon />
</IconButton>
<Drawer
anchor="top"
open={open}
onClose={toggleDrawer(false)}
>
<Box>
<IconButton onClick={toggleDrawer(false)}>
<CloseRoundedIcon />
</IconButton>
</Box>
<MenuList>
<Link style={{ textDecoration: 'none' }} to="/">
<StyledMenuItem selected={active == '1'}> Главная </StyledMenuItem>
</Link>
<Link style={{ textDecoration: 'none' }} to="/list">
<StyledMenuItem selected={active == '2'}>Список зданий</StyledMenuItem>
</Link>
<Link style={{ textDecoration: 'none' }} to="/chart">
<StyledMenuItem selected={active == '3'}>Диаграммы</StyledMenuItem>
</Link>
</MenuList>
</Drawer>
</Box>
</StyledToolbar>
</Container>
</AppBar>
);
}
export default NavBar;

118
labs/lab8/src/data.tsx Normal file
View File

@@ -0,0 +1,118 @@
import Image1 from './images/image1.jpg';
import Image2 from './images/image2.jpg';
import Image3 from './images/image3.jpg';
import Image4 from './images/image4.jpg';
import Image5 from './images/image5.jpg';
import Image6 from './images/image6.jpg';
import Image7 from './images/image7.jpg';
import Image8 from './images/image8.jpg';
import Image9 from './images/image9.jpg';
import Image10 from './images/image10.jpg';
const structures = [
{
img: Image1,
title: "Раффлз-Сити, Китай",
description: [
`Раффлз-Сити — комплекс небоскрёбов, расположенный в китайском городе Чунцин, в деловом районе Юйчжун. Построен в 2019 году. Архитекторами комплекса выступили Моше Сафди и Чунцинский архитектурный институт, владельцем является сингапурская группа CapitaLand.`,
`В состав многофункционального комплекса Раффлз-Сити входят восемь высотных башен и обширный подиум, в котором располагаются продуктовый супермаркет, магазины, автосалоны, рестораны, выставочные залы и паркинг. Общая площадь комплекса — свыше 1,1 млн м²,
в том числе пятиэтажный торговый центр — 230 тыс. м², офисы — 160 тыс. м² и мультиплекс сети CGV — 5,6 тыс. м². В одной из 350-метровых башен Раффлз-Сити расположен пятизвёздочный отель InterContinental,
также в комплексе насчитывается 1,4 тыс. жилых апартаментов сети Ascott и 26,4 тыс. парковочных мест.`
],
},
{
img: Image2,
title: "Авичи-Арена, Швеция",
description: [
`Авичи-Арена - 85-метровая многоцелевая арена в Стокгольме. Второе по величине сферическое сооружение в мире. Место проведения концертов и спортивных мероприятий.
Арена находится в микрорайоне Глобен-Сити, созданном специально для неё. Имеет вместимость 16 000 человек во время концертов и 13 850 во время хоккейных матчей.`,
`Арена была построена специально к чемпионату мира по хоккею 1989 года и открыта 19 февраля 1989 года. Олицетворяет собой Солнце в Шведской Солнечной системе, крупнейшей в мире модели Солнечной системы.`
]
},
{
img: Image3,
title: "Труба ГРЭС-2, Казахстан",
description: [
`Железобетонная дымовая труба, построенная в 1987 году, имея высоту 420 м, является самой высокой в мире и занесена в Книгу рекордов Гиннесса.
Суммарная масса трубы составляет 60 тысяч тонн, её диаметр у основания составляет 44 м, диаметр устья — 14,2 м.`,
`ГРЭС-2 вырабатывает электроэнергию из высокозольного экибастузского угля двумя энергоблоками по 500 МВт, имеет установленную мощность 1000 МВт. Два её энергоблока вырабатывают около 12 % всей электроэнергии,
производимой в республике. Энергия ГРЭС-2 предназначена для обеспечения севера Казахстана. Потребителями являются десятки предприятий не только Казахстана, но и России.`
]
},
{
img: Image4,
title: 'Бурдж-Халифа, Дубай, ОАЭ',
description: [
`Небоскрёб высотой 828 метров, самое высокое сооружение в мире. Форма здания напоминает сталагмит.`,
`Строительство небоскрёба началось в 2004 году и шло со скоростью 1—2 этажа в неделю. Ежедневно на строительстве работало до 12 000 рабочих.
На его создание ушло около 320 тыс. м³ бетона и более 60 тыс. тонн стальной арматуры.
Бетонные работы были завершены после возведения 160 этажа, далее шла сборка 180-метрового шпиля из металлических конструкций.`
]
},
{
img: Image5,
title: "Интинская радиомачта, Инта, Россия",
description: [
`На подъезде к железнодорожной станции Инта 1, кроме величественных вершин Урала, бросается в глаза металлическая вышка-мачта высотой 462,8 метра.
Она больше чем знаменитая Эйфелева башня, но меньше на 77 метров, чем телевизионная Останкинская в Москве. Антенна навигационной системы «Чайка» предназначена
для определения координат самолётов и кораблей с погрешностью 50100 метров. Вышка-мачта находится на территории действующей военной части.`,
`По конструкции это классическая GP антенна. Длинна волны передачи - приёма кратна высоте. Планировалось, чтотакие антенны должны были быть построены в нескольких
точках по Полярному кругу.`
]
},
{
img: Image6,
title: "Ворота Запада, США",
description: [
`Арка в Сент-Луисе, также известная под именем «Врата на запад» — мемориал, являющийся частью Джефферсоновского национального экспансиального мемориала, а также визитной карточкой Сент-Луиса, штат Миссури, США.`,
`Арка была спроектирована финско-американским архитектором Ээро Саариненом в 1947 году. Её высота 192 метра в самой высокой точке, ширина её основания также 192 метра.
Таким образом арка является самым высоким памятником на территории США. Её строительство началось 12 февраля 1963 года и было закончено 28 октября 1965 года. Памятник открылся для посетителей 24 июля 1967 года.`
]
},
{
img: Image7,
title: 'CN Tower, Торонто, Канада',
description: [
`553.3-метровая телевизионная башня. Была самым высоким свободно стоящим сооружением в мире с 1976 по 2007 год, до сих пор остаётся
таковым в Западном полушарии. Является символом Торонто. На высоте 447 м находится астрономическая обсерватория.`,
`Земляные работы для сооружения железобетонной конструкции с последующим натяжением арматуры весом 130 000т начались 12 февраля 1973 г.,
а уже 2 апреля 1975 г. возведение башни было завершено.`
]
},
{
img: Image8,
title: 'Небесное дерево, Токио, Япония',
description: [
`Телевизионная башня в районе Сумида самая высокая среди телебашен мира. Высота телебашни вместе с антенной составляет 634 метра.
Высота башни была выбрана так, чтобы цифры: 6 (на старом японском «му»), 3 («са»), 4 («си») были созвучны «Мусаси» — названию исторической области,
где находится современный Токио.`,
`Здание напоминает пятиярусную пагоду, что хорошо сочетается с историческим районом Асакуса на другом берегу реки.
Основание башни напоминает штатив; с высоты примерно 350 м она имеет цилиндрическую форму, позволяющую наслаждаться панорамными видами реки и города.`
]
},
{
img: Image9,
title: 'The Clock Towers, Мекка, Саудовская Аравия',
description: [
`Отель «Королевская часовая башня» имеет высоту 601 м. Его строительство которого завершилось в 2012 году. Внешне здание отдалённо напоминает Биг-Бен в Лондоне,
при этом выше последнего в 6 раз.`,
`На Королевской башне установлены часы диаметром 43 метра (длина часовой стрелки составляет 17 метров, минутной — 22),
расположенные на высоте более 400 метров над землёй. Четыре их циферблата установлены по четырём сторонам света. Часы видны из любого места города,
и являются самыми большими и самыми высотными часами в мире`
]
},
{
img: Image10,
title: 'Merdeka 118, Куала-Лумпур, Малайзия',
description: [
`Общая высота здания составляет 678.9 м, причём более 160 м приходится на шпиль. Строительство Merdeka 118 началось в 2014 году.`,
`Название «Merdeka» означает «независимость», оно отсылает к наименованию расположенного рядом с башней стадиона,
который известен как место официального провозглашения независимости.`,
`Здание находится в центре Куала-Лумпура. В небоскрёбе откроется первый отель Park Hyatt в Малайзии.
Также в здании будут расположены самая высокая смотровая площадка в Юго-Восточной Азии, торговый центр, музей, мечеть, офисы и квартиры.`
]
},
];
export default structures;

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -0,0 +1,12 @@
import Navbar from "../components/Navbar";
import BuildingsGrid from "./components/BuildingsGrid";
function List() {
return (
<div>
<Navbar active="2"/>
<BuildingsGrid/>
</div>
);
}
export default List;

View File

@@ -0,0 +1,28 @@
import { DataGrid } from "@mui/x-data-grid";
import type { GridRowsProp, GridColDef } from "@mui/x-data-grid";
import Container from '@mui/material/Container';
import { ruRU } from '@mui/x-data-grid/locales';
import buildings from "../table";
function BuildingsGrid() {
const rows: GridRowsProp = buildings;
const columns: GridColDef[] = [
{ field: 'Название', headerName: 'Название', flex: 1},
{ field: 'Тип', flex: 0.5},
{ field: 'Страна', flex: 0.5},
{ field: 'Город', flex: 0.5},
{ field: 'Год' },
{ field: 'Высота'},
]
return (
<Container maxWidth="lg" sx={{height: '700px', mt: '20px'}}>
<DataGrid
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
rows={rows}
columns={columns}
/>
</Container>
)
}
export default BuildingsGrid;

View File

@@ -0,0 +1,583 @@
const buildings = [
{
"id": 1,
"Название": "Бурдж-Халифа",
"Тип": "Небоскрёб",
"Страна": "ОАЭ",
"Город": "Дубай",
"Год": 2010,
"Высота": 828
},
{
"id": 2,
"Название": "Варшавская радиомачта",
"Тип": "Антенная мачта",
"Страна": "Польша",
"Город": "Константинов",
"Год": 1974,
"Высота": 646.38
},
{
"id": 3,
"Название": "Tokyo Skytree",
"Тип": "Бетонная башня",
"Страна": "Япония",
"Город": "Токио",
"Год": 2012,
"Высота": 634
},
{
"id": 4,
"Название": "Шанхайская башня",
"Тип": "Небоскрёб",
"Страна": "КНР",
"Город": "Шанхай",
"Год": 2013,
"Высота": 632
},
{
"id": 5,
"Название": "Телерадиомачта KVLY-TV",
"Тип": "Радиомачта",
"Страна": "США",
"Город": "Бланчард",
"Год": 1963,
"Высота": 629
},
{
"id": 6,
"Название": "Телебашня Гуанчжоу",
"Тип": "Гиперболоидная башня",
"Страна": "КНР",
"Город": "Гуанчжоу",
"Год": 2009,
"Высота": 600
},
{
"id": 7,
"Название": "Международный финансовый центр Пинань",
"Тип": "Небоскрёб",
"Страна": "КНР",
"Город": "Шэньчжэнь",
"Год": 2017,
"Высота": 600
},
{
"id": 8,
"Название": "Lotte World Tower",
"Тип": "Небоскрёб",
"Страна": "Южная Корея",
"Город": "Сеул",
"Год": 2017,
"Высота": 555
},
{
"id": 9,
"Название": "Си-Эн Тауэр",
"Тип": "Бетонная башня",
"Страна": "Канада",
"Город": "Торонто",
"Год": 1976,
"Высота": 553
},
{
"id": 10,
"Название": "Останкинская башня",
"Тип": "Бетонная башня",
"Страна": "Россия",
"Город": "Москва",
"Год": 1967,
"Высота": 540.1
},
{
"id": 11,
"Название": "Уиллис-тауэр",
"Тип": "Небоскрёб",
"Страна": "США",
"Город": "Чикаго",
"Год": 1974,
"Высота": 527.3
},
{
"id": 12,
"Название": "Тайбэй 101",
"Тип": "Небоскрёб",
"Страна": "Тайвань",
"Город": "Тайбэй",
"Год": 2004,
"Высота": 509.2
},
{
"id": 13,
"Название": "Шанхайский всемирный финансовый центр",
"Тип": "Небоскрёб",
"Страна": "КНР",
"Город": "Шанхай",
"Год": 2008,
"Высота": 492
},
{
"id": 14,
"Название": "Международный коммерческий центр",
"Тип": "Небоскрёб",
"Страна": "Гонконг",
"Город": "Гонконг",
"Год": 2009,
"Высота": 484
},
{
"id": 15,
"Название": "Восточная жемчужина",
"Тип": "Бетонная башня",
"Страна": "КНР",
"Город": "Шанхай",
"Год": 1994,
"Высота": 467.9
},
{
"id": 16,
"Название": "Лахта-центр",
"Тип": "Небоскрёб",
"Страна": "Россия",
"Город": "Санкт-Петербург",
"Год": 2018,
"Высота": 462
},
{
"id": 17,
"Название": "Landmark 81",
"Тип": "Небоскрёб",
"Страна": "Вьетнам",
"Город": "Хошимин",
"Год": 2018,
"Высота": 461.2
},
{
"id": 18,
"Название": "875 Норт-Мичиган-авеню",
"Тип": "Небоскрёб",
"Страна": "США",
"Город": "Чикаго",
"Год": 1969,
"Высота": 457.2
},
{
"id": 19,
"Название": "Петронас. башня 1 и 2",
"Тип": "Небоскрёб",
"Страна": "Малайзия",
"Город": "Куала-Лумпур",
"Год": 1998,
"Высота": 452
},
{
"id": 20,
"Название": "Финансовый центр Наньцзин-Гринлэнд",
"Тип": "Небоскрёб",
"Страна": "КНР",
"Город": "Нанкин",
"Год": 2009,
"Высота": 450
},
{
"id": 21,
"Название": "Эмпайр-стейт-билдинг",
"Тип": "Небоскрёб",
"Страна": "США",
"Город": "Нью-Йорк",
"Год": 1931,
"Высота": 448.7
},
{
"id": 22,
"Название": "Международный финансовый центр. башня зап.",
"Тип": "Небоскрёб",
"Страна": "КНР",
"Город": "Гуанчжоу",
"Год": 2010,
"Высота": 437.5
},
{
"id": 23,
"Название": "Kingkey 100",
"Тип": "Небоскрёб",
"Страна": "КНР",
"Город": "Шэньчжэнь",
"Год": 2011,
"Высота": 439.8
},
{
"id": 24,
"Название": "Бордже Милад",
"Тип": "Бетонная башня",
"Страна": "Иран",
"Город": "Тегеран",
"Год": 2003,
"Высота": 435
},
{
"id": 25,
"Название": "Парк-авеню. 432",
"Тип": "Небоскрёб",
"Страна": "США",
"Город": "Нью-Йорк",
"Год": 2015,
"Высота": 425.5
},
{
"id": 26,
"Название": "Международная гостиница и башня Трампа",
"Тип": "Небоскрёб",
"Страна": "США",
"Город": "Чикаго",
"Год": 2009,
"Высота": 423.4
},
{
"id": 27,
"Название": "Менара Куала-Лумпур",
"Тип": "Бетонная башня",
"Страна": "Малайзия",
"Город": "Куала-Лумпур",
"Год": 1995,
"Высота": 421
},
{
"id": 28,
"Название": "Цзинь Мао",
"Тип": "Небоскрёб",
"Страна": "КНР",
"Город": "Шанхай",
"Год": 1999,
"Высота": 420.5
},
{
"id": 29,
"Название": "Экибастузская ГРЭС-2",
"Тип": "Дымовая труба",
"Страна": "Казахстан",
"Город": "Экибастуз",
"Год": 1987,
"Высота": 419.7
},
{
"id": 30,
"Название": "Международный финансовый центр",
"Тип": "Небоскрёб",
"Страна": "Гонконг",
"Город": "Гонконг",
"Год": 2003,
"Высота": 415.8
},
{
"id": 31,
"Название": "Тяньцзиньская телебашня",
"Тип": "Бетонная башня",
"Страна": "КНР",
"Город": "Тяньцзинь",
"Год": 1991,
"Высота": 415.2
},
{
"id": 32,
"Название": "Башня Аль-Хамра",
"Тип": "Небоскрёб",
"Страна": "Кувейт",
"Город": "Кувейт",
"Год": 2010,
"Высота": 412
},
{
"id": 33,
"Название": "Пекинская телебашня",
"Тип": "Бетонная башня",
"Страна": "КНР",
"Город": "Пекин",
"Год": 1992,
"Высота": 405
},
{
"id": 34,
"Название": "Башня CITIC",
"Тип": "Небоскрёб",
"Страна": "КНР",
"Город": "Гуанчжоу",
"Год": 1997,
"Высота": 391.1
},
{
"id": 35,
"Название": "Киевская телебашня",
"Тип": "Решётчатая мачта",
"Страна": "Украина",
"Город": "Киев",
"Год": 1973,
"Высота": 385
},
{
"id": 36,
"Название": "Башня Сёньхин",
"Тип": "Небоскрёб",
"Страна": "КНР",
"Город": "Шэньчжэнь",
"Год": 1996,
"Высота": 384
},
{
"id": 37,
"Название": "Абу-Даби Плаза",
"Тип": "Небоскрёб",
"Страна": "Казахстан",
"Город": "Астана",
"Год": 2015,
"Высота": 382
},
{
"id": 38,
"Название": "Бурдж-Мохаммед-бин-Рашид",
"Тип": "Небоскрёб",
"Страна": "ОАЭ",
"Город": "Абу-Даби",
"Год": 2014,
"Высота": 381
},
{
"id": 39,
"Название": "Inco Superstack",
"Тип": "Дымовая труба",
"Страна": "Канада",
"Город": "Copper Cliff",
"Год": 1971,
"Высота": 380
},
{
"id": 40,
"Название": "Тантекс-Скай-Тауэр",
"Тип": "Небоскрёб",
"Страна": "Тайвань",
"Город": "Гаосюн",
"Год": 1997,
"Высота": 378
},
{
"id": 41,
"Название": "JW Marriott Marquis Dubai. 1 и 2",
"Тип": "Небоскрёб",
"Страна": "ОАЭ",
"Город": "Дубай",
"Год": 2010,
"Высота": 376
},
{
"id": 42,
"Название": "Ташкентская телебашня",
"Тип": "Башня",
"Страна": "Узбекистан",
"Город": "Ташкент",
"Год": 1985,
"Высота": 374.9
},
{
"id": 43,
"Название": "Башня Федерация «Восток»",
"Тип": "Небоскрёб",
"Страна": "Россия",
"Город": "Москва",
"Год": 2016,
"Высота": 374
},
{
"id": 44,
"Название": "Сентрал-плаза",
"Тип": "Небоскрёб",
"Страна": "Гонконг",
"Город": "Гонконг",
"Год": 1992,
"Высота": 374
},
{
"id": 45,
"Название": "Башня Освобождения",
"Тип": "Бетонная башня",
"Страна": "Кувейт",
"Город": "Кувейт",
"Год": 1996,
"Высота": 372
},
{
"id": 46,
"Название": "Телебашня «Коктобе»",
"Тип": "Башня",
"Страна": "Казахстан",
"Город": "Алматы",
"Год": 1983,
"Высота": 371.5
},
{
"id": 47,
"Название": "Дымовая труба электростанции",
"Тип": "Дымовая труба",
"Страна": "США",
"Город": "Homer City",
"Год": 1977,
"Высота": 371
},
{
"id": 48,
"Название": "Дымовая труба Берёзовской ГРЭС",
"Тип": "Дымовая труба",
"Страна": "Россия",
"Город": "Шарыпово",
"Год": 1985,
"Высота": 370
},
{
"id": 49,
"Название": "Рижская телебашня",
"Тип": "Бетонная башня",
"Страна": "Латвия",
"Город": "Рига",
"Год": 1987,
"Высота": 368.5
},
{
"id": 50,
"Название": "Берлинская телебашня",
"Тип": "Бетонная башня",
"Страна": "Германия",
"Город": "Берлин",
"Год": 1969,
"Высота": 368
},
{
"id": 51,
"Название": "Дымовая труба электростанции.",
"Тип": "Дымовая труба",
"Страна": "США",
"Город": "Маундсвилл",
"Год": 1968,
"Высота": 367.6
},
{
"id": 52,
"Название": "Башня Банка Китая",
"Тип": "Небоскрёб",
"Страна": "Гонконг",
"Город": "Гонконг",
"Год": 1990,
"Высота": 367.4
},
{
"id": 53,
"Название": "Башня Банка Америки",
"Тип": "Небоскрёб",
"Страна": "США",
"Город": "Нью-Йорк",
"Год": 2008,
"Высота": 366
},
{
"id": 54,
"Название": "Башня Алмас",
"Тип": "Небоскрёб",
"Страна": "ОАЭ",
"Город": "Дубай",
"Год": 2008,
"Высота": 363
},
{
"id": 55,
"Название": "Дымовая труба электростанции в Трбовле",
"Тип": "Дымовая труба",
"Страна": "Словения",
"Город": "Трбовле",
"Год": 1976,
"Высота": 360
},
{
"id": 56,
"Название": "Endesa Termic ",
"Тип": "Дымовая труба",
"Страна": "Испания",
"Город": "Ферроль",
"Год": 1974,
"Высота": 356
},
{
"id": 57,
"Название": "SEG Plaza",
"Тип": "Небоскрёб",
"Страна": "КНР",
"Город": "Шэньчжэнь",
"Год": 2000,
"Высота": 355.8
},
{
"id": 58,
"Название": "First Canadian Place",
"Тип": "Небоскрёб",
"Страна": "Канада",
"Город": "Торонто",
"Год": 1976,
"Высота": 355
},
{
"id": 59,
"Название": "Эмиратская офисная башня",
"Тип": "Небоскрёб",
"Страна": "ОАЭ",
"Город": "Дубай",
"Год": 2000,
"Высота": 354.6
},
{
"id": 60,
"Название": "ОКО Южная башня",
"Тип": "Небоскрёб",
"Страна": "Россия",
"Город": "Москва",
"Год": 2015,
"Высота": 354
},
{
"id": 61,
"Название": "Виннцкая телемачта",
"Тип": "Радиомачта",
"Страна": "Украина",
"Город": "Винница",
"Год": 1961,
"Высота": 354
},
{
"id": 62,
"Название": "Медеплавильный завод",
"Тип": "Дымовая труба",
"Страна": "Румыния",
"Город": "Бая-Маре",
"Год": 1995,
"Высота": 351.5
},
{
"id": 63,
"Название": "Стратосфера Лас-Вегас",
"Тип": "Бетонная башня",
"Страна": "США",
"Город": "Лас-Вегас",
"Год": 1996,
"Высота": 350.2
},
{
"id": 64,
"Название": "Дымовая труба Сырдарьинской электростанции",
"Тип": "Дымовая труба",
"Страна": "Узбекистан",
"Город": "Сырдарья",
"Год": 1980,
"Высота": 350
}
];
export default buildings;

40
labs/lab8/src/main.tsx Normal file
View File

@@ -0,0 +1,40 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import {
createBrowserRouter,
RouterProvider,
} from "react-router-dom";
import List from "./list/List";
import Main from "./main/Main";
import Building from "./building/Building";
import Chart from "./chart/Chart";
const router = createBrowserRouter([
{
path: "",
element: <Main />,
},
{
path: "/list",
element: <List />,
},
{
path: "/chart",
element: <Chart />,
},
{
path: "/building/:id",
element: <Building />,
},
]);
import './styles/index.css'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<RouterProvider router={router} />
</StrictMode>,
)

View File

@@ -0,0 +1,13 @@
import Navbar from "../components/Navbar";
import Gallery from "./components/Gallery";
import Content from "./components/Content";
function Main() {
return (
<div>
<Navbar active="1"/>
<Gallery/>
<Content/>
</div>
);
}
export default Main;

View File

@@ -0,0 +1,55 @@
import Card from '@mui/material/Card';
import CardActions from '@mui/material/CardActions';
import CardContent from '@mui/material/CardContent';
import CardMedia from '@mui/material/CardMedia';
import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import { styled } from '@mui/material/styles';
import { Link } from 'react-router-dom';
interface ComponentProps {
building: {
img: string,
title: string,
description: string[]
},
cardNum: number;
idx: number;
}
const StyledTypography = styled(Typography)(({ theme }) => ({
color: theme.palette.text.secondary,
textAlign: 'justify',
marginBottom: '1em',
}));
function BuildCard({ building,cardNum,idx} : ComponentProps) {
return (
<Card style={cardNum%2==0?{'flexDirection':'row-reverse'}:{}}sx={{ display: 'flex' }} >
<CardMedia
component="img"
alt={ building.title }
image={ building.img }
/>
<Box>
<CardContent>
<Typography gutterBottom variant="h5" >
{ building.title }
</Typography>
{ building.description.map((item, ind) => (
<StyledTypography key={ind} variant="body2">
{ item }
</StyledTypography>
))}
</CardContent>
<CardActions sx={{ justifyContent: cardNum%2!=0?'end':"start"}} >
<Link key={cardNum} to={"/building/" + idx}><Button size="small">Подробнее</Button></Link>
</CardActions>
</Box>
</Card>
)
}
export default BuildCard;

View File

@@ -0,0 +1,21 @@
import Container from '@mui/material/Container';
import Grid from '@mui/material/Grid';
import structures from "../../data";
import BuildCard from "./BuildCard"
const cardData = [structures[3], structures[6], structures[9], structures[7]]
function Content() {
return (
<Container maxWidth="xl">
<Grid container spacing={{ xs: 3, md: 6 }}>
{cardData.map((item, index) => (
<Grid key={index} size={{ xs: 12, md: 6 }} >
<BuildCard building={ item } cardNum={index} idx={[3,6,9,7][index]} />
</Grid>
))}
</Grid>
</Container>
);
}
export default Content;

View File

@@ -0,0 +1,45 @@
import ImageList from '@mui/material/ImageList';
import ImageListItem from '@mui/material/ImageListItem';
import structures from "../../data";
import Box from '@mui/material/Box';
import Container from '@mui/material/Container';
import ImageListItemBar from '@mui/material/ImageListItemBar';
import { Link } from 'react-router-dom';
const imgData = structures.slice(0, -1);
function Gallery() {
return (
<Container maxWidth="lg">
<Box sx={{ width: 800, height: 585, overflowY: 'scroll', m: '20px auto' }}>
<ImageList
variant="masonry"
sx={{
columnCount: {
xs: '1 !important',
sm: '2 !important',
md: '3 !important',
lg: '4 !important',
},
}}
gap={8}>
{imgData.map((item, index) => (
<Link key={index} to={"/building/" + index}>
<ImageListItem key={item.img}>
<img
srcSet={item.img}
src={item.img}
alt={item.title}
loading="lazy"
/>
<ImageListItemBar position="bottom" title={item.title} />
</ImageListItem>
</Link>
))}
</ImageList>
</Box>
</Container>
);
}
export default Gallery;

View File

@@ -0,0 +1,184 @@
.counter {
font-size: 16px;
padding: 5px 10px;
border-radius: 5px;
color: var(--accent);
background: var(--accent-bg);
border: 2px solid transparent;
transition: border-color 0.3s;
margin-bottom: 24px;
&:hover {
border-color: var(--accent-border);
}
&:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
}
.hero {
position: relative;
.base,
.framework,
.vite {
inset-inline: 0;
margin: 0 auto;
}
.base {
width: 170px;
position: relative;
z-index: 0;
}
.framework,
.vite {
position: absolute;
}
.framework {
z-index: 1;
top: 34px;
height: 28px;
transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
scale(1.4);
}
.vite {
z-index: 0;
top: 107px;
height: 26px;
width: auto;
transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
scale(0.8);
}
}
#center {
display: flex;
flex-direction: column;
gap: 25px;
place-content: center;
place-items: center;
flex-grow: 1;
@media (max-width: 1024px) {
padding: 32px 20px 24px;
gap: 18px;
}
}
#next-steps {
display: flex;
border-top: 1px solid var(--border);
text-align: left;
& > div {
flex: 1 1 0;
padding: 32px;
@media (max-width: 1024px) {
padding: 24px 20px;
}
}
.icon {
margin-bottom: 16px;
width: 22px;
height: 22px;
}
@media (max-width: 1024px) {
flex-direction: column;
text-align: center;
}
}
#docs {
border-right: 1px solid var(--border);
@media (max-width: 1024px) {
border-right: none;
border-bottom: 1px solid var(--border);
}
}
#next-steps ul {
list-style: none;
padding: 0;
display: flex;
gap: 8px;
margin: 32px 0 0;
.logo {
height: 18px;
}
a {
color: var(--text-h);
font-size: 16px;
border-radius: 6px;
background: var(--social-bg);
display: flex;
padding: 6px 12px;
align-items: center;
gap: 8px;
text-decoration: none;
transition: box-shadow 0.3s;
&:hover {
box-shadow: var(--shadow);
}
.button-icon {
height: 18px;
width: 18px;
}
}
@media (max-width: 1024px) {
margin-top: 20px;
flex-wrap: wrap;
justify-content: center;
li {
flex: 1 1 calc(50% - 8px);
}
a {
width: 100%;
justify-content: center;
box-sizing: border-box;
}
}
}
#spacer {
height: 88px;
border-top: 1px solid var(--border);
@media (max-width: 1024px) {
height: 48px;
}
}
.ticks {
position: relative;
width: 100%;
&::before,
&::after {
content: '';
position: absolute;
top: -4.5px;
border: 5px solid transparent;
}
&::before {
left: 0;
border-left-color: var(--border);
}
&::after {
right: 0;
border-right-color: var(--border);
}
}

View File

@@ -0,0 +1,111 @@
:root {
--text: #6b6375;
--text-h: #08060d;
--bg: #fff;
--border: #e5e4e7;
--code-bg: #f4f3ec;
--accent: #aa3bff;
--accent-bg: rgba(170, 59, 255, 0.1);
--accent-border: rgba(170, 59, 255, 0.5);
--social-bg: rgba(244, 243, 236, 0.5);
--shadow:
rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px;
--sans: system-ui, 'Segoe UI', Roboto, sans-serif;
--heading: system-ui, 'Segoe UI', Roboto, sans-serif;
--mono: ui-monospace, Consolas, monospace;
font: 18px/145% var(--sans);
letter-spacing: 0.18px;
color-scheme: light dark;
color: var(--text);
background: var(--bg);
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
@media (max-width: 1024px) {
font-size: 16px;
}
}
@media (prefers-color-scheme: dark) {
:root {
--text: #9ca3af;
--text-h: #f3f4f6;
--bg: #16171d;
--border: #2e303a;
--code-bg: #1f2028;
--accent: #c084fc;
--accent-bg: rgba(192, 132, 252, 0.15);
--accent-border: rgba(192, 132, 252, 0.5);
--social-bg: rgba(47, 48, 58, 0.5);
--shadow:
rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px;
}
#social .button-icon {
filter: invert(1) brightness(2);
}
}
#root {
width: 1126px;
max-width: 100%;
margin: 0 auto;
text-align: center;
border-inline: 1px solid var(--border);
min-height: 100svh;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
body {
margin: 0;
}
h1,
h2 {
font-family: var(--heading);
font-weight: 500;
color: var(--text-h);
}
h1 {
font-size: 56px;
letter-spacing: -1.68px;
margin: 32px 0;
@media (max-width: 1024px) {
font-size: 36px;
margin: 20px 0;
}
}
h2 {
font-size: 24px;
line-height: 118%;
letter-spacing: -0.24px;
margin: 0 0 8px;
@media (max-width: 1024px) {
font-size: 20px;
}
}
p {
margin: 0;
}
code,
.counter {
font-family: var(--mono);
display: inline-flex;
border-radius: 4px;
color: var(--text-h);
}
code {
font-size: 15px;
line-height: 135%;
padding: 4px 8px;
background: var(--code-bg);
}