Docker + Jenkfins File + v0.1

This commit is contained in:
Marco Santos
2024-11-18 10:42:44 +00:00
parent 964bad93f1
commit 048d3ea82f
32 changed files with 505 additions and 975 deletions

View File

@@ -5,6 +5,8 @@
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@headlessui/react": "^2.2.0",
"@heroicons/react": "^2.1.5",
"@mui/icons-material": "^5.15.15",
"@mui/material": "^5.15.15",
"@testing-library/jest-dom": "^5.17.0",
@@ -50,6 +52,7 @@
"@types/react-helmet": "^6.1.11",
"eslint": "^8.57.0",
"eslint-config-react-app": "^7.0.1",
"jest-editor-support": "^31.1.2"
"jest-editor-support": "^31.1.2",
"tailwindcss": "^3.4.13"
}
}

View File

@@ -1,99 +1,20 @@
import * as React from 'react';
import { PaletteMode } from '@mui/material';
import CssBaseline from '@mui/material/CssBaseline';
import Box from '@mui/material/Box';
import Divider from '@mui/material/Divider';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import ToggleButton from '@mui/material/ToggleButton';
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
import { Helmet } from 'react-helmet';
import getLPTheme from './GeradoresTheme';
import AppAppBar from './components/AppAppBar';
import React from 'react';
import Navbar from './components/Navbar';
import Hero from './components/Hero';
import LogoCollection from './components/LogoCollection';
import Highlights from './components/Highlights';
import Pricing from './components/Pricing';
import Features from './components/Features';
import Testimonials from './components/Testimonials';
import FAQ from './components/FAQ';
import FeatureSection from './components/Features';
import Footer from './components/Footer';
import GeradorCC from './components/GeradorNIF';
interface ToggleCustomThemeProps {
showCustomTheme: Boolean;
toggleCustomTheme: () => void;
}
function ToggleCustomTheme({
showCustomTheme,
toggleCustomTheme,
}: ToggleCustomThemeProps) {
const App = () => {
return (
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
width: '100dvw',
position: 'fixed',
bottom: 24,
}}
>
<ToggleButtonGroup
color="primary"
exclusive
value={showCustomTheme}
onChange={toggleCustomTheme}
aria-label="Platform"
sx={{
backgroundColor: 'background.default',
'& .Mui-selected': {
pointerEvents: 'none',
},
}}
>
<ToggleButton value>
Custom theme
</ToggleButton>
<ToggleButton value={false}>Material Design 2</ToggleButton>
</ToggleButtonGroup>
</Box>
);
}
function App() {
/*const [mode, setMode] = React.useState<PaletteMode>('light');
const [showCustomTheme, setShowCustomTheme] = React.useState(true);
const LPtheme = createTheme(getLPTheme(mode));
const defaultTheme = createTheme({ palette: { mode } });
const toggleColorMode = () => {
setMode((prev) => (prev === 'dark' ? 'light' : 'dark'));
};
const toggleCustomTheme = () => {
setShowCustomTheme((prev) => !prev);
};*/
return (
<div className="App">
<Helmet>
<meta charSet="utf-8" />
<title>Geradores</title>
</Helmet>
{ /*<ThemeProvider theme={showCustomTheme ? LPtheme : defaultTheme}></ThemeProvider>*/}
<div>
<CssBaseline />
<GeradorCC />
</div>
<div className="min-h-screen flex flex-col">
<Navbar />
<main className="flex-grow">
<Hero />
<FeatureSection />
</main>
<Footer />
</div>
);
}
};
export default App;

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

View File

@@ -1,227 +0,0 @@
import * as React from 'react';
import { PaletteMode } from '@mui/material';
import Box from '@mui/material/Box';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import Button from '@mui/material/Button';
import IconButton from '@mui/material/IconButton';
import Container from '@mui/material/Container';
import Divider from '@mui/material/Divider';
import MenuItem from '@mui/material/MenuItem';
import Drawer from '@mui/material/Drawer';
import MenuIcon from '@mui/icons-material/Menu';
import CloseRoundedIcon from '@mui/icons-material/CloseRounded';
import ToggleColorMode from './ToggleColorMode';
import Sitemark from './SitemarkIcon';
interface AppAppBarProps {
mode: PaletteMode;
toggleColorMode: () => void;
}
export default function AppAppBar({ mode, toggleColorMode }: AppAppBarProps) {
const [open, setOpen] = React.useState(false);
const toggleDrawer = (newOpen: boolean) => () => {
setOpen(newOpen);
};
const scrollToSection = (sectionId: string) => {
const sectionElement = document.getElementById(sectionId);
const offset = 128;
if (sectionElement) {
const targetScroll = sectionElement.offsetTop - offset;
sectionElement.scrollIntoView({ behavior: 'smooth' });
window.scrollTo({
top: targetScroll,
behavior: 'smooth',
});
setOpen(false);
}
};
return (
<AppBar
position="fixed"
sx={{
boxShadow: 0,
bgcolor: 'transparent',
backgroundImage: 'none',
mt: 2,
}}
>
<Container maxWidth="lg">
<Toolbar
variant="regular"
sx={(theme) => ({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
flexShrink: 0,
borderRadius: '999px',
bgcolor:
theme.palette.mode === 'light'
? 'hsla(220, 60%, 99%, 0.6)'
: 'hsla(220, 0%, 0%, 0.7)',
backdropFilter: 'blur(24px)',
maxHeight: 40,
border: '1px solid',
borderColor: 'divider',
boxShadow:
theme.palette.mode === 'light'
? '0 1px 2px hsla(210, 0%, 0%, 0.05), 0 2px 12px hsla(210, 100%, 80%, 0.5)'
: '0 1px 2px hsla(210, 0%, 0%, 0.5), 0 2px 12px hsla(210, 100%, 25%, 0.3)',
})}
>
<Box
sx={{
flexGrow: 1,
display: 'flex',
alignItems: 'center',
px: 0,
}}
>
<Sitemark />
<Box sx={{ display: { xs: 'none', md: 'flex' } }}>
<Button
variant="text"
color="info"
size="small"
onClick={() => scrollToSection('features')}
>
Features
</Button>
<Button
variant="text"
color="info"
size="small"
onClick={() => scrollToSection('testimonials')}
>
Testimonials
</Button>
<Button
variant="text"
color="info"
size="small"
onClick={() => scrollToSection('highlights')}
>
Highlights
</Button>
<Button
variant="text"
color="info"
size="small"
onClick={() => scrollToSection('pricing')}
>
Pricing
</Button>
<Button
variant="text"
color="info"
size="small"
onClick={() => scrollToSection('faq')}
sx={{ minWidth: 0 }}
>
FAQ
</Button>
</Box>
</Box>
<Box
sx={{
display: { xs: 'none', md: 'flex' },
gap: 0.5,
alignItems: 'center',
}}
>
<ToggleColorMode mode={mode} toggleColorMode={toggleColorMode} />
<Button
color="primary"
variant="text"
size="small"
component="a"
href="/material-ui/getting-started/templates/sign-in/"
target="_blank"
>
Sign in
</Button>
<Button
color="primary"
variant="contained"
size="small"
component="a"
href="/material-ui/getting-started/templates/sign-up/"
target="_blank"
>
Sign up
</Button>
</Box>
<Box sx={{ display: { sm: 'flex', md: 'none' } }}>
<IconButton aria-label="Menu button" onClick={toggleDrawer(true)}>
<MenuIcon />
</IconButton>
<Drawer anchor="top" open={open} onClose={toggleDrawer(false)}>
<Box
sx={{
p: 2,
backgroundColor: 'background.default',
}}
>
<Box
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}}
>
<ToggleColorMode mode={mode} toggleColorMode={toggleColorMode} />
<IconButton onClick={toggleDrawer(false)}>
<CloseRoundedIcon />
</IconButton>
</Box>
<Divider sx={{ my: 3 }} />
<MenuItem onClick={() => scrollToSection('features')}>
Features
</MenuItem>
<MenuItem onClick={() => scrollToSection('testimonials')}>
Testimonials
</MenuItem>
<MenuItem onClick={() => scrollToSection('highlights')}>
Highlights
</MenuItem>
<MenuItem onClick={() => scrollToSection('pricing')}>
Pricing
</MenuItem>
<MenuItem onClick={() => scrollToSection('faq')}>FAQ</MenuItem>
<MenuItem>
<Button
color="primary"
variant="contained"
component="a"
href="/material-ui/getting-started/templates/sign-up/"
target="_blank"
fullWidth
>
Sign up
</Button>
</MenuItem>
<MenuItem>
<Button
color="primary"
variant="outlined"
component="a"
href="/material-ui/getting-started/templates/sign-in/"
target="_blank"
fullWidth
>
Sign in
</Button>
</MenuItem>
</Box>
</Drawer>
</Box>
</Toolbar>
</Container>
</AppBar>
);
}

View File

@@ -1,272 +1,27 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Card from '@mui/material/Card';
import Chip from '@mui/material/Chip';
import Container from '@mui/material/Container';
import Grid from '@mui/material/Grid';
import Link from '@mui/material/Link';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded';
import DevicesRoundedIcon from '@mui/icons-material/DevicesRounded';
import EdgesensorHighRoundedIcon from '@mui/icons-material/EdgesensorHighRounded';
import ViewQuiltRoundedIcon from '@mui/icons-material/ViewQuiltRounded';
import React from 'react';
const items = [
{
icon: <ViewQuiltRoundedIcon />,
title: 'Dashboard',
description:
'This item could provide a snapshot of the most important metrics or data points related to the product.',
imageLight: 'url("/static/images/templates/templates-images/dash-light.png")',
imageDark: 'url("/static/images/templates/templates-images/dash-dark.png")',
},
{
icon: <EdgesensorHighRoundedIcon />,
title: 'Mobile integration',
description:
'This item could provide information about the mobile app version of the product.',
imageLight: 'url("/static/images/templates/templates-images/mobile-light.png")',
imageDark: 'url("/static/images/templates/templates-images/mobile-dark.png")',
},
{
icon: <DevicesRoundedIcon />,
title: 'Available on all platforms',
description:
'This item could let users know the product is available on all platforms, such as web, mobile, and desktop.',
imageLight: 'url("/static/images/templates/templates-images/devices-light.png")',
imageDark: 'url("/static/images/templates/templates-images/devices-dark.png")',
},
];
function FeatureSection() {
return (
<section id="features" className="py-20 bg-white">
<div className="container mx-auto px-4 text-center">
<h2 className="text-3xl font-bold text-gray-800">Why Use Our Generator?</h2>
<div className="mt-8 grid grid-cols-1 md:grid-cols-3 gap-8">
<div className="p-6 bg-gray-50 rounded-lg shadow-md">
<h3 className="text-xl font-bold text-gray-800">NIF (N<EFBFBD>mero Identifica<EFBFBD><EFBFBD>o Fiscal)</h3>
<p className="mt-4 text-gray-600">Quickly generate valid Portuguese Tax Identification Numbers (NIF) for testing.</p>
</div>
<div className="p-6 bg-gray-50 rounded-lg shadow-md">
<h3 className="text-xl font-bold text-gray-800">NISS (N<EFBFBD>mero Identifica<EFBFBD><EFBFBD>o Seguran<EFBFBD>a Social)</h3>
<p className="mt-4 text-gray-600">Create Portuguese Social Security Numbers (NISS) easily with one click.</p>
</div>
<div className="p-6 bg-gray-50 rounded-lg shadow-md">
<h3 className="text-xl font-bold text-gray-800">Cart<EFBFBD>o de Cidad<EFBFBD>o</h3>
<p className="mt-4 text-gray-600">Generate valid Citizen Card numbers for testing purposes in a few seconds.</p>
</div>
</div>
</div>
</section>
);
};
export default function Features() {
const [selectedItemIndex, setSelectedItemIndex] = React.useState(0);
const handleItemClick = (index: number) => {
setSelectedItemIndex(index);
};
const selectedFeature = items[selectedItemIndex];
return (
<Container id="features" sx={{ py: { xs: 8, sm: 16 } }}>
<Grid container spacing={6}>
<Grid item xs={12} md={6}>
<div>
<Typography component="h2" variant="h4" color="text.primary">
Product features
</Typography>
<Typography
variant="body1"
color="text.secondary"
sx={{ mb: { xs: 2, sm: 4 } }}
>
Provide a brief overview of the key features of the product. For
example, you could list the number of features, their types or
benefits, and add-ons.
</Typography>
</div>
<Grid container item gap={1} sx={{ display: { xs: 'auto', sm: 'none' } }}>
{items.map(({ title }, index) => (
<Chip
key={index}
label={title}
onClick={() => handleItemClick(index)}
sx={(theme) => ({
...(selectedItemIndex === index && {
borderColor:
theme.palette.mode === 'light'
? 'primary.light'
: 'primary.dark',
background:
'linear-gradient(to bottom right, hsl(210, 98%, 48%), hsl(210, 98%, 35%))',
color: 'hsl(0, 0%, 100%)',
'& .MuiChip-label': {
color: 'hsl(0, 0%, 100%)',
},
}),
})}
/>
))}
</Grid>
<Card
variant="outlined"
sx={{
display: { xs: 'auto', sm: 'none' },
mt: 4,
}}
>
<Box
sx={{
backgroundImage: (theme) =>
theme.palette.mode === 'light'
? items[selectedItemIndex].imageLight
: items[selectedItemIndex].imageDark,
backgroundSize: 'cover',
backgroundPosition: 'center',
minHeight: 280,
}}
/>
<Box sx={{ px: 2, pb: 2 }}>
<Typography color="text.primary" fontWeight="medium" gutterBottom>
{selectedFeature.title}
</Typography>
<Typography color="text.secondary" variant="body2" sx={{ mb: 1.5 }}>
{selectedFeature.description}
</Typography>
<Link
color="primary"
variant="body2"
fontWeight="bold"
sx={{
display: 'inline-flex',
alignItems: 'center',
'& > svg': { transition: '0.2s' },
'&:hover > svg': { transform: 'translateX(2px)' },
}}
>
<span>Learn more</span>
<ChevronRightRoundedIcon
fontSize="small"
sx={{ mt: '1px', ml: '2px' }}
/>
</Link>
</Box>
</Card>
<Stack
direction="column"
justifyContent="center"
alignItems="flex-start"
spacing={2}
useFlexGap
sx={{ width: '100%', display: { xs: 'none', sm: 'flex' } }}
>
{items.map(({ icon, title, description }, index) => (
<Card
key={index}
component={Button}
onClick={() => handleItemClick(index)}
sx={(theme) => ({
p: 3,
height: 'fit-content',
width: '100%',
background: 'none',
...(selectedItemIndex === index && {
backgroundColor: 'action.selected',
borderColor:
theme.palette.mode === 'light'
? 'primary.light'
: 'primary.dark',
}),
'&:hover': {
background:
theme.palette.mode === 'light'
? 'linear-gradient(to bottom right, hsla(210, 100%, 97%, 0.5) 25%, hsla(210, 100%, 90%, 0.3) 100%)'
: 'linear-gradient(to right bottom, hsla(210, 100%, 12%, 0.2) 25%, hsla(210, 100%, 16%, 0.2) 100%)',
borderColor:
theme.palette.mode === 'light'
? 'primary.light'
: 'primary.dark',
boxShadow:
theme.palette.mode === 'light'
? '0px 2px 8px hsla(0, 0%, 0%, 0.1)'
: '0px 1px 8px hsla(210, 100%, 25%, 0.5) ',
},
})}
>
<Box
sx={{
width: '100%',
display: 'flex',
textAlign: 'left',
flexDirection: { xs: 'column', md: 'row' },
alignItems: { md: 'center' },
gap: 2.5,
}}
>
<Box
sx={(theme) => ({
color:
theme.palette.mode === 'light' ? 'grey.400' : 'grey.600',
...(selectedItemIndex === index && {
color: 'primary.main',
}),
})}
>
{icon}
</Box>
<div>
<Typography
color="text.primary"
fontWeight="medium"
gutterBottom
>
{title}
</Typography>
<Typography
color="text.secondary"
variant="body2"
sx={{ mb: 1.5 }}
>
{description}
</Typography>
<Link
color="primary"
variant="body2"
fontWeight="bold"
sx={{
display: 'inline-flex',
alignItems: 'center',
'& > svg': { transition: '0.2s' },
'&:hover > svg': { transform: 'translateX(2px)' },
}}
onClick={(event) => {
event.stopPropagation();
}}
>
<span>Learn more</span>
<ChevronRightRoundedIcon
fontSize="small"
sx={{ mt: '1px', ml: '2px' }}
/>
</Link>
</div>
</Box>
</Card>
))}
</Stack>
</Grid>
<Grid
item
xs={12}
md={6}
sx={{ display: { xs: 'none', sm: 'flex' }, width: '100%' }}
>
<Card
variant="outlined"
sx={{
height: '100%',
width: '100%',
display: { xs: 'none', sm: 'flex' },
pointerEvents: 'none',
}}
>
<Box
sx={{
m: 'auto',
width: 420,
height: 500,
backgroundSize: 'contain',
backgroundImage: (theme) =>
theme.palette.mode === 'light'
? items[selectedItemIndex].imageLight
: items[selectedItemIndex].imageDark,
}}
/>
</Card>
</Grid>
</Grid>
</Container>
);
}
export default FeatureSection;

View File

@@ -1,215 +1,16 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Container from '@mui/material/Container';
import IconButton from '@mui/material/IconButton';
import InputLabel from '@mui/material/InputLabel';
import Link from '@mui/material/Link';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import React from 'react';
import { visuallyHidden } from '@mui/utils';
const Footer = () => {
return (
<footer id="contact" className="bg-gray-800 py-6">
<div className="container mx-auto px-4 text-center text-white">
<p className="text-sm">&copy; {new Date().getFullYear()} GeneratorApp. All rights reserved.</p>
<p className="mt-2">
<a href="mailto:info@generatorapp.com" className="underline">info@generatorapp.com</a>
</p>
</div>
</footer>
);
};
import FacebookIcon from '@mui/icons-material/GitHub';
import LinkedInIcon from '@mui/icons-material/LinkedIn';
import TwitterIcon from '@mui/icons-material/X';
import SitemarkIcon from './SitemarkIcon';
function Copyright() {
return (
<Typography variant="body2" color="text.secondary" mt={1}>
{'Copyright © '}
<Link href="https://mui.com/">Sitemark&nbsp;</Link>
{new Date().getFullYear()}
</Typography>
);
}
export default function Footer() {
return (
<Container
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: { xs: 4, sm: 8 },
py: { xs: 8, sm: 10 },
textAlign: { sm: 'center', md: 'left' },
}}
>
<Box
sx={{
display: 'flex',
flexDirection: { xs: 'column', sm: 'row' },
width: '100%',
justifyContent: 'space-between',
}}
>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
gap: 4,
minWidth: { xs: '100%', sm: '60%' },
}}
>
<Box sx={{ width: { xs: '100%', sm: '60%' } }}>
<SitemarkIcon />
<Typography variant="body2" fontWeight={600} gutterBottom sx={{ mt: 2 }}>
Join the newsletter
</Typography>
<Typography variant="body2" color="text.secondary" mb={2}>
Subscribe for weekly updates. No spams ever!
</Typography>
<Stack direction="row" spacing={1} useFlexGap>
<InputLabel htmlFor="email-newsletter" sx={visuallyHidden}>
Email
</InputLabel>
<TextField
id="email-newsletter"
hiddenLabel
size="small"
variant="outlined"
fullWidth
aria-label="Enter your email address"
placeholder="Your email address"
inputProps={{
autocomplete: 'off',
ariaLabel: 'Enter your email address',
}}
/>
<Button variant="contained" color="primary" sx={{ flexShrink: 0 }}>
Subscribe
</Button>
</Stack>
</Box>
</Box>
<Box
sx={{
display: { xs: 'none', sm: 'flex' },
flexDirection: 'column',
gap: 1,
}}
>
<Typography variant="body2" fontWeight="medium">
Product
</Typography>
<Link color="text.secondary" variant="body2" href="#">
Features
</Link>
<Link color="text.secondary" variant="body2" href="#">
Testimonials
</Link>
<Link color="text.secondary" variant="body2" href="#">
Highlights
</Link>
<Link color="text.secondary" variant="body2" href="#">
Pricing
</Link>
<Link color="text.secondary" variant="body2" href="#">
FAQs
</Link>
</Box>
<Box
sx={{
display: { xs: 'none', sm: 'flex' },
flexDirection: 'column',
gap: 1,
}}
>
<Typography variant="body2" fontWeight="medium">
Company
</Typography>
<Link color="text.secondary" variant="body2" href="#">
About us
</Link>
<Link color="text.secondary" variant="body2" href="#">
Careers
</Link>
<Link color="text.secondary" variant="body2" href="#">
Press
</Link>
</Box>
<Box
sx={{
display: { xs: 'none', sm: 'flex' },
flexDirection: 'column',
gap: 1,
}}
>
<Typography variant="body2" fontWeight="medium">
Legal
</Typography>
<Link color="text.secondary" variant="body2" href="#">
Terms
</Link>
<Link color="text.secondary" variant="body2" href="#">
Privacy
</Link>
<Link color="text.secondary" variant="body2" href="#">
Contact
</Link>
</Box>
</Box>
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
pt: { xs: 4, sm: 8 },
width: '100%',
borderTop: '1px solid',
borderColor: 'divider',
}}
>
<div>
<Link color="text.secondary" variant="body2" href="#">
Privacy Policy
</Link>
<Typography display="inline" sx={{ mx: 0.5, opacity: 0.5 }}>
&nbsp;&nbsp;
</Typography>
<Link color="text.secondary" variant="body2" href="#">
Terms of Service
</Link>
<Copyright />
</div>
<Stack
direction="row"
justifyContent="left"
spacing={1}
useFlexGap
sx={{
color: 'text.secondary',
}}
>
<IconButton
color="inherit"
href="https://github.com/mui"
aria-label="GitHub"
sx={{ alignSelf: 'center' }}
>
<FacebookIcon />
</IconButton>
<IconButton
color="inherit"
href="https://twitter.com/MaterialUI"
aria-label="X"
sx={{ alignSelf: 'center' }}
>
<TwitterIcon />
</IconButton>
<IconButton
color="inherit"
href="https://www.linkedin.com/company/mui/"
aria-label="LinkedIn"
sx={{ alignSelf: 'center' }}
>
<LinkedInIcon />
</IconButton>
</Stack>
</Box>
</Container>
);
}
export default Footer;

View File

@@ -1,132 +1,23 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Container from '@mui/material/Container';
import InputLabel from '@mui/material/InputLabel';
import Link from '@mui/material/Link';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import React from 'react';
import { visuallyHidden } from '@mui/utils';
function Hero(){
return (
<section id="home" className="bg-blue-50 py-20">
<div className="container mx-auto text-center">
<h1 className="text-5xl font-bold text-gray-800">
Generate Your NIF, NISS, and Cart<EFBFBD>o de Cidad<EFBFBD>o Easily
</h1>
<p className="mt-4 text-gray-600">
Use our simple and efficient platform to generate valid testing numbers quickly.
</p>
<div className="mt-6">
<a href="#generate" className="px-6 py-3 bg-blue-600 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700">
Get Started
</a>
</div>
</div>
</section>
);
};
export default function Hero() {
return (
<Box
id="hero"
sx={(theme) => ({
width: '100%',
backgroundImage:
theme.palette.mode === 'light'
? 'radial-gradient(ellipse 80% 50% at 50% -20%, hsl(210, 100%, 90%), transparent)'
: 'radial-gradient(ellipse 80% 50% at 50% -20%, hsl(210, 100%, 16%), transparent)',
backgroundRepeat: 'no-repeat',
})}
>
<Container
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
pt: { xs: 14, sm: 20 },
pb: { xs: 8, sm: 12 },
}}
>
<Stack
spacing={2}
alignItems="center"
useFlexGap
sx={{ width: { xs: '100%', sm: '70%' } }}
>
<Typography
variant="h1"
sx={{
display: 'flex',
flexDirection: { xs: 'column', sm: 'row' },
alignItems: 'center',
fontSize: 'clamp(3rem, 10vw, 3.5rem)',
}}
>
Our&nbsp;latest&nbsp;
<Typography
component="span"
variant="h1"
sx={{
fontSize: 'inherit',
color: (theme) =>
theme.palette.mode === 'light' ? 'primary.main' : 'primary.light',
}}
>
products
</Typography>
</Typography>
<Typography
textAlign="center"
color="text.secondary"
sx={{ width: { sm: '100%', md: '80%' } }}
>
Explore our cutting-edge dashboard, delivering high-quality solutions
tailored to your needs. Elevate your experience with top-tier features
and services.
</Typography>
<Stack
direction={{ xs: 'column', sm: 'row' }}
spacing={1}
useFlexGap
sx={{ pt: 2, width: { xs: '100%', sm: 'auto' } }}
>
<InputLabel htmlFor="email-hero" sx={visuallyHidden}>
Email
</InputLabel>
<TextField
id="email-hero"
hiddenLabel
size="small"
variant="outlined"
aria-label="Enter your email address"
placeholder="Your email address"
inputProps={{
autocomplete: 'off',
ariaLabel: 'Enter your email address',
}}
/>
<Button variant="contained" color="primary">
Start now
</Button>
</Stack>
<Typography variant="caption" textAlign="center">
By clicking &quot;Start now&quot; you agree to our&nbsp;
<Link href="#" color="primary">
Terms & Conditions
</Link>
.
</Typography>
</Stack>
<Box
id="image"
sx={(theme) => ({
mt: { xs: 8, sm: 10 },
alignSelf: 'center',
height: { xs: 200, sm: 700 },
width: '100%',
backgroundImage:
theme.palette.mode === 'light'
? 'url("/static/images/templates/templates-images/hero-light.png")'
: 'url("/static/images/templates/templates-images/hero-dark.png")',
backgroundSize: 'cover',
borderRadius: '12px',
outline: '1px solid',
outlineColor:
theme.palette.mode === 'light'
? 'hsla(220, 25%, 80%, 0.5)'
: 'hsla(210, 100%, 80%, 0.1)',
boxShadow:
theme.palette.mode === 'light'
? '0 0 12px 8px hsla(220, 25%, 80%, 0.2)'
: '0 0 24px 12px hsla(210, 100%, 25%, 0.2)',
})}
/>
</Container>
</Box>
);
}
export default Hero;

View File

@@ -0,0 +1,108 @@
import React, { useState, useEffect } from 'react';
import { Transition } from '@headlessui/react';
import { MoonIcon, SunIcon } from '@heroicons/react/24/outline';
import Logo from '../assets/logotipo.png';
const Navbar = () => {
const [isOpen, setIsOpen] = useState(false);
const [darkMode, setDarkMode] = useState(false);
// Apply dark mode based on the toggle state
useEffect(() => {
if (darkMode) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}, [darkMode]);
return (
<nav className="bg-blue-900 dark:bg-gray-800 shadow-lg sticky top-0 z-50">
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-16">
{/* Logo e Nome da Marca */}
<div className="flex items-center space-x-2">
<img src={Logo} alt="FactoryID Logo" className="h-8 w-auto" />
</div>
{/* Desktop Navigation Links */}
<div className="hidden md:flex space-x-8">
<a href="#home" className="text-gray-800 dark:text-white hover:text-yellow-300 transition duration-300 transform hover:scale-110">
Home
</a>
<a href="#features" className="text-gray-800 dark:text-white hover:text-yellow-300 transition duration-300 transform hover:scale-110">
Features
</a>
<a href="#contact" className="text-gray-800 dark:text-white hover:text-yellow-300 transition duration-300 transform hover:scale-110">
Contact
</a>
<a href="#get-started" className="bg-yellow-300 text-gray-800 px-4 py-2 rounded-lg shadow-md hover:bg-yellow-400 transition duration-300">
Get Started
</a>
</div>
{/* Dark Mode Toggle */}
<div className="flex items-center space-x-4">
<button
onClick={() => setDarkMode(!darkMode)}
className="flex items-center px-2 py-1 rounded-md bg-gray-200 dark:bg-gray-700 dark:text-gray-200 text-gray-800 hover:bg-gray-300 dark:hover:bg-gray-600"
>
{darkMode ? (
<SunIcon className="h-6 w-6 text-yellow-400" />
) : (
<MoonIcon className="h-6 w-6 text-blue-500" />
)}
<span className="ml-2">{darkMode ? 'Light Mode' : 'Dark Mode'}</span>
</button>
{/* Mobile Menu Button */}
<button
onClick={() => setIsOpen(!isOpen)}
type="button"
className="text-gray-800 dark:text-white md:hidden"
aria-controls="mobile-menu"
aria-expanded="false"
>
<span className="sr-only">Open main menu</span>
<svg className="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d={isOpen ? "M6 18L18 6M6 6l12 12" : "M4 6h16M4 12h16M4 18h16"} />
</svg>
</button>
</div>
</div>
</div>
{/* Mobile Menu Dropdown */}
<Transition
show={isOpen}
enter="transition ease-out duration-200 transform"
enterFrom="opacity-0 -translate-y-2"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-2"
>
<div className="md:hidden bg-gray-200 dark:bg-gray-700" id="mobile-menu">
<div className="px-2 pt-2 pb-3 space-y-1 sm:px-3">
<a href="#home" className="block px-3 py-2 rounded-md text-gray-800 dark:text-white hover:bg-purple-600">
Home
</a>
<a href="#features" className="block px-3 py-2 rounded-md text-gray-800 dark:text-white hover:bg-purple-600">
Features
</a>
<a href="#contact" className="block px-3 py-2 rounded-md text-gray-800 dark:text-white hover:bg-purple-600">
Contact
</a>
<a href="#get-started" className="block px-3 py-2 rounded-md bg-yellow-300 text-gray-800 text-center">
Get Started
</a>
</div>
</div>
</Transition>
</nav>
);
};
export default Navbar;

View File

@@ -1,13 +1,3 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -3,7 +3,7 @@ import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Helmet } from 'react-helmet'
//import { Helmet } from 'react-helmet'
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement

View File

@@ -0,0 +1,11 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: 'class', // Enable dark mode with a class
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}