login ve register ekranları oluşturuldu

This commit is contained in:
2025-11-12 18:24:40 +03:00
parent fc2e1e841f
commit 3365d43110
6 changed files with 298 additions and 2 deletions

6
public/google.svg Normal file
View File

@@ -0,0 +1,6 @@
<svg width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
<path d="M17.64 9.2045c0-.6395-.0573-1.2527-.1636-1.8409H9v3.4814h4.8445a4.1437 4.1437 0 0 1-1.7977 2.7168v2.2582h2.9047c1.7028-1.5664 2.6885-3.8746 2.6885-6.6155z" fill="#4285F4"/>
<path d="M9 18c2.43 0 4.4673-.8055 5.9568-2.1791l-2.9047-2.2582c-.8054.54-1.8368.8573-3.0521.8573-2.3473 0-4.3346-1.5845-5.0432-3.7168H.957v2.3314A8.9978 8.9978 0 0 0 9 18z" fill="#34A853"/>
<path d="M3.9568 10.7032a5.4016 5.4016 0 0 1 0-3.4064V4.9655H.957a8.9991 8.9991 0 0 0 0 8.0689l2.9998-2.3312z" fill="#FBBC05"/>
<path d="M9 3.5573c1.3191 0 2.5036.4532 3.4341 1.3428l2.5763-2.5764C13.4673.8918 11.43.0009 9 .0009A8.9978 8.9978 0 0 0 .957 4.9655l2.9998 2.3313C4.6654 5.1418 6.6527 3.5573 9 3.5573z" fill="#EA4335"/>
</svg>

After

Width:  |  Height:  |  Size: 802 B

View File

@@ -71,6 +71,7 @@ const App = () => {
<Typography <Typography
component="button" component="button"
type="button" type="button"
onClick={() => navigate('/login')}
sx={{ sx={{
background: 'none', background: 'none',
border: 'none', border: 'none',
@@ -86,8 +87,8 @@ const App = () => {
> >
Login Login
</Typography> </Typography>
<Button variant="contained" color="primary" size="small"> <Button variant="contained" color="primary" size="small" onClick={() => navigate('/register')}>
Sign Up Register
</Button> </Button>
</Stack> </Stack>
</Stack> </Stack>

View File

@@ -9,6 +9,8 @@ import BulkCropStep from './components/BulkCropStep';
import OcrStep from './components/OcrStep'; import OcrStep from './components/OcrStep';
import EpubStep from './components/EpubStep'; import EpubStep from './components/EpubStep';
import DownloadStep from './components/DownloadStep'; import DownloadStep from './components/DownloadStep';
import Login from './pages/auth/Login';
import Register from './pages/auth/Register';
const theme = createTheme({ const theme = createTheme({
palette: { palette: {
@@ -135,6 +137,8 @@ const router = createBrowserRouter([
{ path: wizardSteps[5].path, element: <DownloadStep /> }, { path: wizardSteps[5].path, element: <DownloadStep /> },
], ],
}, },
{ path: '/login', element: <Login /> },
{ path: '/register', element: <Register /> },
]); ]);
ReactDOM.createRoot(document.getElementById('root')).render( ReactDOM.createRoot(document.getElementById('root')).render(

275
src/pages/auth/AuthPage.jsx Normal file
View File

@@ -0,0 +1,275 @@
import {
Box,
Button,
Container,
Divider,
Link,
Paper,
Stack,
TextField,
Typography,
} from '@mui/material';
import { Link as RouterLink } from 'react-router-dom';
const copy = {
login: {
eyebrow: 'Tek panel, sonsuz çıktı',
heading: 'imgpub stüdyona giriş yap',
body:
'OCR, crop ve EPUB üretimini tek akışta yöneten imgpub hesabına eriş. Taslaklarını, kapaklarını ve sürümlerini nerede kalmış olursan ol devam ettir.',
submit: 'Giriş yap',
switchLabel: 'Hesabın yok mu?',
switchLink: { to: '/register', label: 'Hemen kaydol' },
google: 'Google ile giriş yap',
highlights: [
'Kütüphanendeki projeleri bulutta sakla',
'OCR sonrası metinleri EPUB şablonlarına aktar',
'Toplu crop ile sayfa düzenini koru',
],
},
register: {
eyebrow: 'Dakikalar içinde hazır',
heading: 'Yeni imgpub hesabı oluştur',
body:
'Taradığın sayfaları düzenle, OCR ile Türkçe metni temizle ve EPUB olarak dışa aktar. Kayıt ol, yayın kulübeni dilediğin zaman genişlet.',
submit: 'Hesabımı oluştur',
switchLabel: 'Zaten hesabın var mı?',
switchLink: { to: '/login', label: 'Giriş yap' },
google: 'Google ile devam et',
highlights: [
'Akıllı crop önerileri ile zamandan kazan',
'OCR çıktısını EPUB ve PDF olarak taşı',
'Kapak ve önizleme görsellerini tek tuşla üret',
],
},
};
const fields = {
login: [
{ name: 'email', label: 'Email adresi', type: 'email' },
{ name: 'password', label: 'Şifre', type: 'password' },
],
register: [
{ name: 'name', label: 'Ad Soyad', type: 'text' },
{ name: 'email', label: 'Email adresi', type: 'email' },
{ name: 'password', label: 'Şifre', type: 'password' },
],
};
const AuthPage = ({ mode }) => {
const variant = copy[mode];
const formFields = fields[mode];
return (
<Box
sx={{
minHeight: '100vh',
background: 'linear-gradient(180deg, #F9F7F4 0%, #F3EEE5 60%, #F9F7F4 100%)',
display: 'flex',
alignItems: 'center',
py: { xs: 6, md: 10 },
}}
>
<Container maxWidth="lg">
<Paper
elevation={0}
sx={{
borderRadius: 5,
overflow: 'hidden',
p: 0,
display: 'grid',
gridTemplateColumns: { xs: '1fr', md: '1fr 1fr' },
}}
>
<Box sx={{ p: { xs: 4, md: 6 } }}>
<Stack spacing={3} maxWidth={420} mx="auto">
<Stack spacing={1}>
<Typography
variant="h4"
sx={{ fontFamily: '"Caudex", serif', color: '#1C1815', fontWeight: 700, letterSpacing: 1 }}
>
imgpub
</Typography>
<Typography variant="overline" sx={{ color: '#B5AD9A', letterSpacing: 2 }}>
{variant.eyebrow}
</Typography>
<Typography variant="h4" sx={{ color: '#1C1815', fontWeight: 700, lineHeight: 1.2 }}>
{variant.heading}
</Typography>
<Typography sx={{ color: '#5A5751', lineHeight: 1.6 }}>{variant.body}</Typography>
</Stack>
<Stack spacing={2}>
<Button
fullWidth
size="large"
variant="outlined"
startIcon={<Box component="img" src="/google.svg" alt="Google" width={18} height={18} />}
sx={{
borderColor: '#E0DFDC',
color: '#1C1815',
backgroundColor: '#FFFFFF',
borderRadius: 3,
py: 1.5,
fontWeight: 600,
'&:hover': { borderColor: '#CFC8BD', backgroundColor: '#FAF8F6' },
}}
>
{variant.google}
</Button>
<Divider sx={{ color: '#B5AD9A', fontSize: 12 }}>veya e-posta ile</Divider>
<Stack spacing={2} component="form">
{formFields.map((field) => (
<TextField
key={field.name}
type={field.type}
label={field.label}
name={field.name}
fullWidth
variant="outlined"
InputProps={{ sx: { borderRadius: 3 } }}
/>
))}
<Button type="submit" variant="contained" size="large" fullWidth sx={{ py: 1.4 }}>
{variant.submit}
</Button>
</Stack>
{mode === 'login' && (
<Link
component={RouterLink}
to="/register"
underline="none"
sx={{ color: '#C0462A', fontWeight: 600, fontSize: 14, textAlign: 'center' }}
>
Şifreni mi unuttun? Yeni hesap
</Link>
)}
<Typography sx={{ color: '#7B7366', fontSize: 14, textAlign: 'center' }}>
{variant.switchLabel}{' '}
<Link component={RouterLink} to={variant.switchLink.to} underline="none" sx={{ fontWeight: 600 }}>
{variant.switchLink.label}
</Link>
</Typography>
</Stack>
</Stack>
</Box>
<Box
sx={{
backgroundColor: '#F5F1EA',
borderLeft: { md: '1px solid #E4DDD3' },
p: { xs: 4, md: 6 },
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
}}
>
<AuthShowcase mode={mode} />
</Box>
</Paper>
</Container>
</Box>
);
};
const AuthShowcase = ({ mode }) => {
const variant = copy[mode];
return (
<Stack spacing={3} maxWidth={420} mx="auto">
<Box>
<Typography variant="overline" sx={{ color: '#B5AD9A', letterSpacing: 3 }}>
imgpub studio
</Typography>
<Typography variant="h5" sx={{ fontWeight: 700, color: '#1C1815', mt: 1 }}>
Görsellerini EPUB&apos;a çeviren modern akış
</Typography>
<Typography sx={{ mt: 1, color: '#5A5751' }}>
Toplu crop, OCR ve EPUB çıktısını tek yerde birleştir. Taslaklarını paylaşmak için sadece Google hesabın yeterli.
</Typography>
</Box>
<AuthIllustration />
<Stack spacing={1.5}>
{variant.highlights.map((item) => (
<Stack
key={item}
direction="row"
spacing={2}
alignItems="center"
sx={{
backgroundColor: '#FFFFFF',
borderRadius: 3,
border: '1px solid #E3DDD4',
p: 2,
boxShadow: '0 10px 30px rgba(48,40,27,0.08)',
}}
>
<Box
sx={{
width: 42,
height: 42,
borderRadius: 2,
background: 'linear-gradient(135deg, #E7C179 0%, #DBA453 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '#30281B',
fontWeight: 700,
}}
>
</Box>
<Typography sx={{ color: '#1C1815', fontWeight: 600 }}>{item}</Typography>
</Stack>
))}
</Stack>
</Stack>
);
};
const AuthIllustration = () => (
<Box
sx={{
position: 'relative',
borderRadius: 4,
p: 3,
background: 'linear-gradient(145deg, #FFFFFF 0%, #F1EBE1 100%)',
border: '1px solid #E4DDD3',
minHeight: 220,
overflow: 'hidden',
}}
>
<Box
sx={{
position: 'absolute',
inset: 0,
opacity: 0.2,
backgroundImage:
'radial-gradient(circle at 20% 20%, rgba(231,193,121,0.6), transparent 45%), radial-gradient(circle at 80% 0%, rgba(41,97,93,0.4), transparent 40%)',
}}
/>
<Stack spacing={2} position="relative">
<Paper elevation={0} sx={{ borderRadius: 3, p: 2, border: '1px solid #E1D8CD' }}>
<Stack direction="row" spacing={1} alignItems="center">
<Box sx={{ width: 34, height: 34, borderRadius: 2, backgroundColor: '#E7C179' }} />
<Box sx={{ flexGrow: 1 }}>
<Typography sx={{ fontSize: 14, fontWeight: 700, color: '#30281B' }}>OCR &amp; Crop</Typography>
<Typography sx={{ fontSize: 12, color: '#7B7366' }}>Sayfa kenarlarını otomatik hizala</Typography>
</Box>
</Stack>
</Paper>
<Paper elevation={0} sx={{ borderRadius: 3, p: 2.5, border: '1px solid #E1D8CD' }}>
<Typography sx={{ fontSize: 13, color: '#7B7366', mb: 1 }}>EPUB Süreci</Typography>
<Stack spacing={1}>
{['Kapak', 'Metin', 'Önizleme'].map((item) => (
<Stack key={item} direction="row" spacing={1.5} alignItems="center">
<Box sx={{ width: 10, height: 10, borderRadius: '50%', backgroundColor: '#C3B59E' }} />
<Typography sx={{ fontSize: 13, fontWeight: 600, color: '#1C1815' }}>{item}</Typography>
<Box sx={{ flexGrow: 1, height: 4, borderRadius: 999, backgroundColor: '#EFE7DB' }} />
</Stack>
))}
</Stack>
</Paper>
</Stack>
</Box>
);
export default AuthPage;

5
src/pages/auth/Login.jsx Normal file
View File

@@ -0,0 +1,5 @@
import AuthPage from './AuthPage';
const Login = () => <AuthPage mode="login" />;
export default Login;

View File

@@ -0,0 +1,5 @@
import AuthPage from './AuthPage';
const Register = () => <AuthPage mode="register" />;
export default Register;