한글화중

This commit is contained in:
익희 김 2024-12-05 22:06:19 +09:00
parent a783d387a6
commit b9056611c4
11 changed files with 82 additions and 188 deletions

View File

@ -5,6 +5,7 @@ import GuestGuard from 'src/guards/guest';
import { Card, Stack, Container, Typography } from '@mui/material';
// components
import LoginMain from 'src/components/_main/auth/login';
import { lang } from 'src/components/lang/kr';
// Meta information
export const metadata = {
@ -33,10 +34,7 @@ export default async function Login() {
>
<Stack mb={5}>
<Typography textAlign="center" variant="h4" component="h1" gutterBottom>
Login
</Typography>
<Typography textAlign="center" color="text.secondary">
Login to your account to continue
{lang.login}
</Typography>
</Stack>

View File

@ -4,16 +4,16 @@ import GuestGuard from 'src/guards/guest';
import { Card, Container, Typography } from '@mui/material';
// components
import RegisterMain from 'src/components/_main/auth/register';
import { lang } from 'src/components/lang/kr';
// Meta information
export const metadata = {
title: 'Create Your Nextall Account | Join Us for Exclusive Deals and Seamless Shopping',
description:
'Register with Nextall today to unlock a world of exclusive deals, personalized recommendations, and secure transactions. Join our community for a seamless shopping experience. Sign up now and elevate your online shopping journey!',
applicationName: 'Nextall',
authors: 'Nextall',
keywords: 'ecommerce, Nextall, Commerce, Register Nextall, RegisterFrom Nextall'
};
// export const metadata = {
// title: 'Create Your Nextall Account | Join Us for Exclusive Deals and Seamless Shopping',
// description:
// 'Register with Nextall today to unlock a world of exclusive deals, personalized recommendations, and secure transactions. Join our community for a seamless shopping experience. Sign up now and elevate your online shopping journey!',
// applicationName: 'Nextall',
// authors: 'Nextall',
// keywords: 'ecommerce, Nextall, Commerce, Register Nextall, RegisterFrom Nextall'
// };
export default async function Register() {
return (
@ -31,10 +31,7 @@ export default async function Register() {
}}
>
<Typography variant="h4" component="h1" gutterBottom textAlign="center">
Sign up
</Typography>
<Typography color="text.secondary" mb={5} textAlign="center">
Create your account
{lang['Create your account']}
</Typography>
<RegisterMain />
</Card>

View File

@ -2,7 +2,7 @@
import { Box, Container } from '@mui/material';
// components
import HeaderBreadcrumbs from 'src/components/headerBreadcrumbs';
// import HeaderBreadcrumbs from 'src/components/headerBreadcrumbs';
import ProductList from 'src/components/_main/products';
export default async function Listing() {
@ -10,7 +10,7 @@ export default async function Listing() {
<Box>
<Box sx={{ bgcolor: 'background.default' }}>
<Container maxWidth="xl">
<HeaderBreadcrumbs
{/* <HeaderBreadcrumbs
heading="Products"
links={[
{
@ -21,7 +21,7 @@ export default async function Listing() {
name: 'Products'
}
]}
/>
/> */}
<ProductList />
</Container>

View File

@ -12,6 +12,7 @@ import { useQuery } from 'react-query';
import ProductsCarousel from 'src/components/carousels/gridSlider';
// icons
import { IoIosArrowForward } from 'react-icons/io';
import { lang } from 'src/components/lang/kr';
export default function Index() {
const { data, isLoading } = useQuery(['featured-products'], () => api.getFeaturedProducts());
@ -25,7 +26,7 @@ export default function Index() {
>
<Box>
<Typography variant="h2" color="text.primary" mt={{ xs: 4, md: 8 }}>
상품
{lang['Products']}
</Typography>
</Box>
<Button
@ -42,13 +43,13 @@ export default function Index() {
component={NextLink}
href={`/products?featured=true`}
>
View More
{lang['View More']}
</Button>
</Stack>
{!isLoading && !Boolean(data?.data.length) ? (
<Typography variant="h3" color="error.main" textAlign="center">
Products not found
{lang['Products not found']}
</Typography>
) : (
<ProductsCarousel data={data?.data || []} isLoading={isLoading} />
@ -65,9 +66,10 @@ export default function Index() {
}}
endIcon={<IoIosArrowForward />}
component={NextLink}
href={`/categories`}
// href={`/categories`}
href={`/products?featured=true`}
>
View More
{lang['View More']}
</Button>
</Box>
);

View File

@ -10,6 +10,7 @@ import { Typography, Grid, Box, Stack, Paper, Button } from '@mui/material';
import { IoIosArrowForward } from 'react-icons/io';
// component
import ShopCard from 'src/components/cards/shop';
import { lang } from 'src/components/lang/kr';
export default function ShopComponent() {
const { shops = [], isLoading } = useSelector(({ shops }) => shops);
@ -24,11 +25,8 @@ export default function ShopComponent() {
mb={3}
>
<Box width="100%">
<Typography variant="h2" color="text.primary" mt={{ xs: 4, md: 8 }}>
Best Shops
</Typography>
<Typography variant="body1" color="text.secondary" mb={{ xs: 3, md: 5 }}>
Our Highest Rated Shops Where You Can Find What You Are Looking For
<Typography variant="h2" color="text.primary" mt={{ xs: 4, md: 8 }} textAlign="left">
{lang['Best Shops']}
</Typography>
</Box>
<Button
@ -45,7 +43,7 @@ export default function ShopComponent() {
component={NextLink}
href={`/shops`}
>
View More
{lang['View More']}
</Button>
</Stack>
@ -79,7 +77,7 @@ export default function ShopComponent() {
component={NextLink}
href={`/shops`}
>
View More
{lang['View More']}
</Button>
</Box>
</Paper>

View File

@ -11,6 +11,7 @@ import { useQuery } from 'react-query';
import ProductsCarousel from 'src/components/carousels/gridSlider';
// icons
import { IoIosArrowForward } from 'react-icons/io';
import { lang } from 'src/components/lang/kr';
export default function Index() {
const { data, isLoading } = useQuery(['get-top-products'], () => api.getTopRatedProducts());
@ -44,12 +45,12 @@ export default function Index() {
component={NextLink}
href={`/products?top=1`}
>
View More
{lang['View More']}
</Button>
</Stack>
{!isLoading && !Boolean(data?.data.length) ? (
<Typography variant="h3" color="error.main" textAlign="center">
Products not found
{lang['Products not found']}
</Typography>
) : (
<ProductsCarousel data={data?.data || []} isLoading={isLoading} />
@ -68,7 +69,7 @@ export default function Index() {
component={NextLink}
href={`/products?top=1`}
>
View More
{lang['View More']}
</Button>
</Box>
);

View File

@ -66,7 +66,7 @@ export default function ProductListing({ category, subCategory, shop, compaign }
const isMobile = useMediaQuery('(max-width:900px)');
return (
<>
<SortBar
{/* <SortBar
sortData={sortData}
productData={data}
category={subCategory?.parentCategory || category}
@ -74,7 +74,7 @@ export default function ProductListing({ category, subCategory, shop, compaign }
subCategory={subCategory}
isLoading={isLoading}
compaign={compaign}
/>
/> */}
<ProductList data={data} isLoading={isLoading} isMobile={isMobile} />
<Pagination data={data} />
</>

View File

@ -6,7 +6,7 @@ import RouterLink from 'next/link';
import { useSearchParams } from 'next/navigation';
import { useRouter } from 'next-nprogress-bar';
import toast from 'react-hot-toast';
import { lang } from '../lang/kr';
// formik
import { useFormik, Form, FormikProvider } from 'formik';
// cookies
@ -26,10 +26,7 @@ import {
TextField,
IconButton,
InputAdornment,
FormControlLabel,
Button,
Alert,
AlertTitle
FormControlLabel
} from '@mui/material';
import { LoadingButton } from '@mui/lab';
// icons
@ -49,7 +46,7 @@ export default function LoginForm() {
dispatch(setWishlist(data.user.wishlist));
await createCookies('token', data.token);
setloading(false);
toast.success('Logged in successfully!');
toast.success(lang['Logged in successfully!']);
const isAdmin = data.user.role.includes('admin');
const isVendor = data.user.role.includes('vendor');
push(redirect || isAdmin ? '/admin/dashboard' : isVendor ? '/vendor/dashboard' : '/');
@ -60,8 +57,10 @@ export default function LoginForm() {
}
});
const LoginSchema = Yup.object().shape({
email: Yup.string().email('Enter valid email').required('Email is required.'),
password: Yup.string().required('Password is required.').min(8, 'Password should be 8 characters or longer.')
email: Yup.string().email(lang['Enter valid email']).required(lang['Email is required']),
password: Yup.string()
.required(lang['Password is required'])
.min(8, lang['Password should be 8 characters or longer'])
});
const formik = useFormik({
initialValues: {
@ -77,62 +76,15 @@ export default function LoginForm() {
mutate({ email, password });
}
});
const { errors, touched, setFieldValue, values, handleSubmit, getFieldProps } = formik;
const { errors, touched, values, handleSubmit, getFieldProps } = formik;
return (
<>
<Stack
mb={3}
gap={2}
sx={{
'& .MuiAlert-action': {
alignItems: 'center'
}
}}
>
<Alert
severity="primary"
action={
<Button
color="inherit"
size="small"
onClick={() => {
setFieldValue('email', 'admin@nextall.com');
setFieldValue('password', 'test1234');
}}
>
Copy
</Button>
}
>
<AlertTitle>Admin</AlertTitle>
<b>Email:</b> admin@test.com | <b>password:</b> test1234
</Alert>
<Alert
severity="secondary"
action={
<Button
color="inherit"
size="small"
onClick={() => {
setFieldValue('email', 'vendor@nextall.com');
setFieldValue('password', 'test1234');
}}
>
Copy
</Button>
}
>
<AlertTitle>Vendor</AlertTitle>
<b>Email:</b> vendor@test.com | <b>password:</b> test1234
</Alert>
</Stack>
<FormikProvider value={formik}>
<Form autoComplete="off" noValidate onSubmit={handleSubmit}>
<Stack spacing={3}>
<Stack gap={0.5} width={1}>
<Typography variant="overline" color="text.primary" htmlFor="email" component={'label'}>
Email
{lang.Email}
</Typography>
<TextField
id="email"
@ -154,7 +106,7 @@ export default function LoginForm() {
<Stack gap={0.5} width={1}>
<Typography variant="overline" color="text.primary" htmlFor="password" component={'label'}>
Password
{lang.Password}
</Typography>
<TextField
id="password"
@ -184,19 +136,18 @@ export default function LoginForm() {
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ my: 2 }}>
<FormControlLabel
control={<Checkbox {...getFieldProps('remember')} checked={values.remember} />}
label="Remember me"
label={lang['Remember me']}
/>
<Link component={RouterLink} variant="subtitle2" href="/auth/forget-password">
Forgot password
{lang['Forgot password']}
</Link>
</Stack>
<LoadingButton fullWidth size="large" type="submit" variant="contained" loading={loading}>
login
{lang.login}
</LoadingButton>
<Typography variant="subtitle2" mt={3} textAlign="center">
Don{`'`}t you have an account? &nbsp;
<Link href={`/auth/register${redirect ? '?redirect=' + redirect : ''}`} component={RouterLink}>
Register
{lang.Register}
</Link>
</Typography>
</Form>

View File

@ -29,6 +29,7 @@ import { MdLocalPhone } from 'react-icons/md';
import { FaTransgender } from 'react-icons/fa6';
// hooks
import { createCookies } from 'src/hooks/cookies';
import { lang } from '../lang/kr';
export default function RegisterForm() {
const router = useRouter();
@ -49,8 +50,8 @@ export default function RegisterForm() {
const formik = useFormik({
initialValues: {
firstName: '',
lastName: '',
phone: '',
lastName: 'test',
phone: '01012345678',
gender: 'male',
email: '',
password: ''
@ -103,84 +104,10 @@ export default function RegisterForm() {
}}
/>
</Stack>
<Stack gap={0.5} width={1}>
<Typography variant="overline" color="text.primary" htmlFor="lastName" component={'label'}>
Last Name
</Typography>
<TextField
fullWidth
id="lastName"
type="text"
{...getFieldProps('lastName')}
error={Boolean(touched.lastName && errors.lastName)}
helperText={touched.lastName && errors.lastName}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<IoPerson size={24} />
</InputAdornment>
)
}}
/>
</Stack>
</Stack>
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>
<Stack gap={0.5} width={1}>
<Typography variant="overline" color="text.primary" htmlFor="gender" component={'label'}>
Gender
</Typography>
<TextField
id="gender"
select
fullWidth
{...getFieldProps('gender')}
error={Boolean(touched.gender && errors.gender)}
helperText={touched.gender && errors.gender}
InputProps={{
startAdornment: (
<InputAdornment position="start">
{values.gender === 'male' ? (
<IoMdMale size={24} />
) : values.gender === 'female' ? (
<IoMdFemale size={24} />
) : (
<FaTransgender />
)}
</InputAdornment>
)
}}
>
{['Male', 'Female', 'Other'].map((option) => (
<MenuItem key={option} value={option.toLowerCase()}>
{option}
</MenuItem>
))}
</TextField>
</Stack>
<Stack gap={0.5} width={1}>
<Typography variant="overline" color="text.primary" htmlFor="phone" component={'label'}>
Phone
</Typography>
<TextField
fullWidth
id="phone"
type="text"
{...getFieldProps('phone')}
error={Boolean(touched.phone && errors.phone)}
helperText={touched.phone && errors.phone}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<MdLocalPhone size={24} />
</InputAdornment>
)
}}
/>
</Stack>
</Stack>
<Stack gap={0.5} width={1}>
<Typography variant="overline" color="text.primary" htmlFor="email" component={'label'}>
Email
{lang.Email}
</Typography>
<TextField
id="email"
@ -201,7 +128,7 @@ export default function RegisterForm() {
</Stack>
<Stack gap={0.5} width={1}>
<Typography variant="overline" color="text.primary" htmlFor="password" component={'label'}>
Password
{lang.Password}
</Typography>
<TextField
id="password"
@ -229,20 +156,19 @@ export default function RegisterForm() {
</Stack>
<LoadingButton fullWidth size="large" type="submit" variant="contained" loading={loading}>
Register
{lang.Register}
</LoadingButton>
</Stack>
<Typography variant="subtitle2" mt={3} textAlign="center">
Already have an account? &nbsp;
<Link
href={`/auth/login${router.query?.redirect ? '?redirect=' + router.query?.redirect : ''}`}
component={RouterLink}
>
Login
{lang.login}
</Link>
</Typography>
<Typography variant="body2" align="center" color="text.secondary" mt={2}>
{/* <Typography variant="body2" align="center" color="text.secondary" mt={2}>
By registering, I agree to Nextall&nbsp;
<Link underline="always" color="text.primary" href="#" fontWeight={700}>
Terms
@ -252,7 +178,7 @@ export default function RegisterForm() {
Privacy policy
</Link>
.
</Typography>
</Typography> */}
</Form>
</FormikProvider>
);

21
src/components/lang/kr.js Normal file
View File

@ -0,0 +1,21 @@
export const lang = {
"Don't you have an account?": '가입하기',
Register: '가입',
'Forgot password': '비밀번호 찾기',
login: '로그인',
'Remember me': '아이디 저장',
Password: '비밀번호',
Email: '이메일',
'Enter valid email': '정확한 이메일을 입력해주세요',
'Email is required': '이메일은 필수 입니다',
'Password is required': '비밀번호는 필수 입니다',
'Password should be 8 characters or longer': '비밀번호는 8자 이상이 되어야 합니다',
'Logged in successfully!': '로그인 성공!',
'Create your account': '회원가입',
'First Name': '이름',
Register: '가입하기',
'Best Shops': '상점 목록',
'View More': '더보기',
'Products not found': '상품이 준비되지 않았습니다',
Products: '상품'
};

View File

@ -34,23 +34,23 @@
],
"mobile_menu": [
{
"name": "Home",
"name": "",
"href": "/"
},
{
"name": "Search",
"name": "검색",
"href": "/search"
},
{
"name": "Product",
"name": "상품",
"href": "/products"
},
{
"name": "Cart",
"name": "카트",
"href": "/cart"
},
{
"name": "User",
"name": "사용자",
"isUser": true,
"href": "/auth/login"
}