Kaynağa Gözat

feat: add Localization, Pagination with SWR and React Query, Profile page

hover-contact
ntasicc 3 yıl önce
ebeveyn
işleme
0c1e615253

+ 29
- 0
components/cards/profile-card/ProfileCard.jsx Dosyayı Görüntüle

@@ -0,0 +1,29 @@
import Card from '@mui/material/Card';
import CardContent from '@mui/material/CardContent';
import CardMedia from '@mui/material/CardMedia';
import Typography from '@mui/material/Typography';

const ProfileCard = ({ profileData }) => {
return (
<Card sx={{ maxWidth: 345, marginX: 'auto', marginY: 25, boxShadow: 10 }}>
<CardMedia
component="img"
height="140"
image="https://www.business2community.com/wp-content/uploads/2017/08/blank-profile-picture-973460_640.png"
alt="green iguana"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
{profileData.name}
</Typography>
<Typography variant="body2" color="text.secondary">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur
quis odio in libero fringilla pellentesque aliquet et mi. Quisque
maximus lectus a neque luctus, tempus auctor ipsum ultrices.
</Typography>
</CardContent>
</Card>
);
};

export default ProfileCard;

+ 7
- 0
components/cards/profile-card/ProfileCard.mock.js Dosyayı Görüntüle

@@ -0,0 +1,7 @@
const base = {
profileData: { name: 'John Doe' },
};

export const mockProfilePageProps = {
base,
};

+ 20
- 0
components/cards/profile-card/ProfileCard.stories.jsx Dosyayı Görüntüle

@@ -0,0 +1,20 @@
import ProfileCard from './ProfileCard';
import { mockProfilePageProps } from './ProfileCard.mock';

const obj = {
title: 'cards/ProfileCard',
component: ProfileCard,
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
argTypes: {},
}; //eslint-disable-line

export default obj;
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
const Template = (args) => <ProfileCard {...args} />;

export const Base = Template.bind({});
// More on args: https://storybook.js.org/docs/react/writing-stories/args

Base.args = {
...mockProfilePageProps.base,
};

+ 7
- 4
components/forms/forgot-password/ForgotPasswordForm.jsx Dosyayı Görüntüle

@@ -7,12 +7,15 @@ import {
Typography,
} from '@mui/material';
import { useFormik } from 'formik';
import { useTranslation } from 'next-i18next';
import Link from 'next/link';
import React from 'react';
import { LOGIN_PAGE } from '../../../constants/pages';
import { forgotPasswordSchema } from '../../../schemas/forgotPasswordSchema';

const ForgotPasswordForm = () => {
const { t } = useTranslation('forms', 'forgotPass', 'common');

const handleSubmit = (values) => {
console.log('Values', values);
};
@@ -38,7 +41,7 @@ const ForgotPasswordForm = () => {
}}
>
<Typography component="h1" variant="h5">
Forgot password
{t('forgotPass:Title')}
</Typography>
<Box
component="form"
@@ -47,7 +50,7 @@ const ForgotPasswordForm = () => {
>
<TextField
name="email"
label="Email"
label={t('forms:Email')}
margin="normal"
value={formik.values.email}
onChange={formik.handleChange}
@@ -62,10 +65,10 @@ const ForgotPasswordForm = () => {
sx={{ mt: 3, mb: 2 }}
fullWidth
>
Send email
{t('forgotPass:SendBtn')}
</Button>
<Grid container justifyContent="center">
<Link href={LOGIN_PAGE}>Back</Link>
<Link href={LOGIN_PAGE}>{t('common:Back')}</Link>
</Grid>
</Box>
</Box>

+ 10
- 6
components/forms/login/LoginForm.jsx Dosyayı Görüntüle

@@ -10,6 +10,7 @@ import {
} from '@mui/material';
import { useFormik } from 'formik';
import { signIn } from 'next-auth/react';
import { useTranslation } from 'next-i18next';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useState } from 'react';
@@ -22,6 +23,7 @@ import { loginSchema } from '../../../schemas/loginSchema';
import ErrorMessageComponent from '../../mui/ErrorMessageComponent';

const LoginForm = () => {
const { t } = useTranslation('forms', 'login');
const [showPassword, setShowPassword] = useState(false);
const handleClickShowPassword = () => setShowPassword(!showPassword);
const handleMouseDownPassword = () => setShowPassword(!showPassword);
@@ -64,7 +66,7 @@ const LoginForm = () => {
}}
>
<Typography component="h1" variant="h5">
Login
{t('login:Title')}
</Typography>
{error.hasError && <ErrorMessageComponent error={error.errorMessage} />}
<Box
@@ -74,7 +76,7 @@ const LoginForm = () => {
>
<TextField
name="username"
label="Username"
label={t('forms:Username')}
margin="normal"
value={formik.values.username}
onChange={formik.handleChange}
@@ -85,7 +87,7 @@ const LoginForm = () => {
/>
<TextField
name="password"
label="Password"
label={t('forms:Password')}
margin="normal"
type={showPassword ? 'text' : 'password'}
value={formik.values.password}
@@ -110,7 +112,7 @@ const LoginForm = () => {
sx={{ mt: 3, mb: 2 }}
fullWidth
>
Login
{t('login:LoginBtn')}
</Button>
<Grid container>
<Grid
@@ -119,7 +121,9 @@ const LoginForm = () => {
md={6}
sx={{ textAlign: { xs: 'center', md: 'left' } }}
>
<Link href={FORGOT_PASSWORD_PAGE}>Forgot your password?</Link>
<Link href={FORGOT_PASSWORD_PAGE}>
{t('login:ForgotPassword')}
</Link>
</Grid>
<Grid
item
@@ -127,7 +131,7 @@ const LoginForm = () => {
md={6}
sx={{ textAlign: { xs: 'center', md: 'right' } }}
>
<Link href={REGISTER_PAGE}>Dont have an account?</Link>
<Link href={REGISTER_PAGE}>{t('login:NoAccount')}</Link>
</Grid>
</Grid>
</Box>

+ 14
- 9
components/forms/register/RegisterForm.jsx Dosyayı Görüntüle

@@ -9,6 +9,7 @@ import {
Typography,
} from '@mui/material';
import { useFormik } from 'formik';
import { useTranslation } from 'next-i18next';
import Link from 'next/link';
import { useState } from 'react';

@@ -18,6 +19,8 @@ import { registerSchema } from '../../../schemas/registerSchema';
import ErrorMessageComponent from '../../mui/ErrorMessageComponent';

const RegisterForm = () => {
const { t } = useTranslation('forms', 'register');

const [showPassword, setShowPassword] = useState(false);
const handleClickShowPassword = () => setShowPassword(!showPassword);
const handleMouseDownPassword = () => setShowPassword(!showPassword);
@@ -69,7 +72,7 @@ const RegisterForm = () => {
}}
>
<Typography component="h1" variant="h5">
Register
{t('register:Title')}
</Typography>
{error.hasError && <ErrorMessageComponent error={error.errorMessage} />}
<Box
@@ -79,7 +82,7 @@ const RegisterForm = () => {
>
<TextField
name="fullName"
label="Full name"
label={t('forms:FullName')}
margin="normal"
value={formik.values.fullName}
onChange={formik.handleChange}
@@ -90,7 +93,7 @@ const RegisterForm = () => {
/>
<TextField
name="username"
label="Username"
label={t('forms:Username')}
margin="normal"
value={formik.values.username}
onChange={formik.handleChange}
@@ -100,7 +103,7 @@ const RegisterForm = () => {
/>
<TextField
name="email"
label="Email"
label={t('forms:Email')}
margin="normal"
value={formik.values.email}
onChange={formik.handleChange}
@@ -110,7 +113,7 @@ const RegisterForm = () => {
/>
<TextField
name="password"
label="Password"
label={t('forms:Password')}
margin="normal"
type={showPassword ? 'text' : 'password'}
value={formik.values.password}
@@ -131,7 +134,7 @@ const RegisterForm = () => {
/>
<TextField
name="confirmPassword"
label="Confirm password"
label={t('forms:ConfirmPassword')}
margin="normal"
type={showPassword ? 'text' : 'password'}
value={formik.values.confirmPassword}
@@ -161,7 +164,7 @@ const RegisterForm = () => {
sx={{ mt: 3, mb: 2 }}
fullWidth
>
Register
{t('register:RegisterBtn')}
</Button>
<Grid container>
<Grid
@@ -170,7 +173,9 @@ const RegisterForm = () => {
md={6}
sx={{ textAlign: { xs: 'center', md: 'left' } }}
>
<Link href={FORGOT_PASSWORD_PAGE}>Forgot your password?</Link>
<Link href={FORGOT_PASSWORD_PAGE}>
{t('register:ForgotPassword')}
</Link>
</Grid>
<Grid
item
@@ -178,7 +183,7 @@ const RegisterForm = () => {
md={6}
sx={{ textAlign: { xs: 'center', md: 'right' } }}
>
<Link href={LOGIN_PAGE}>Already have an account?</Link>
<Link href={LOGIN_PAGE}>{t('register:HaveAccount')}</Link>
</Grid>
</Grid>
</Box>

+ 30
- 0
components/pagination/react-query/PaginationComponentRQ.jsx Dosyayı Görüntüle

@@ -0,0 +1,30 @@
import { useState } from 'react';
import { usePagination } from '../../../hooks/use-pagination';

const PaginationComponentRQ = () => {
const [pageIndex, setPageIndex] = useState(1);

const { data: paginationData } = usePagination(pageIndex);

return (
<div>
{paginationData?.data.map((item) => (
<div key={item._id}>{item.name}</div>
))}
<button
disabled={pageIndex === 1}
onClick={() => setPageIndex(pageIndex - 1)}
>
Previous
</button>
<button
disabled={pageIndex * 5 > paginationData?.dataCount}
onClick={() => setPageIndex(pageIndex + 1)}
>
Next
</button>
</div>
);
};

export default PaginationComponentRQ;

+ 5
- 0
components/pagination/react-query/PaginationComponentRQ.mock.js Dosyayı Görüntüle

@@ -0,0 +1,5 @@
const base = {};

export const mockPaginationComponentQRProps = {
base,
};

+ 20
- 0
components/pagination/react-query/PaginationComponentRQ.stories.jsx Dosyayı Görüntüle

@@ -0,0 +1,20 @@
import PaginationComponentRQ from './PaginationComponentRQ';
import { mockPaginationComponentQRProps } from './PaginationComponentRQ.mock';

const obj = {
title: 'pagination/PaginationComponentRQ',
component: PaginationComponentRQ,
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
argTypes: {},
}; //eslint-disable-line

export default obj;
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
const Template = (args) => <PaginationComponentRQ {...args} />;

export const Base = Template.bind({});
// More on args: https://storybook.js.org/docs/react/writing-stories/args

Base.args = {
...mockPaginationComponentQRProps.base,
};

+ 34
- 0
components/pagination/swr/PaginationComponentSWR.jsx Dosyayı Görüntüle

@@ -0,0 +1,34 @@
import { useState } from 'react';
import useSWRWithFallbackData from '../../../hooks/use-swr-with-initial-data';
import { getData } from '../../../requests/dataRequest';

const PaginationComponent = ({ initialData = {} }) => {
const [pageIndex, setPageIndex] = useState(1);

const fetcher = (page) => getData(page);
const { data: paginationData } = useSWRWithFallbackData(pageIndex, fetcher, {
fallbackData: initialData,
});

return (
<div>
{paginationData?.data?.map((item) => (
<div key={item._id}>{item.name}</div>
))}
<button
disabled={pageIndex === 1}
onClick={() => setPageIndex(pageIndex - 1)}
>
Previous
</button>
<button
disabled={pageIndex * 5 > paginationData?.dataCount}
onClick={() => setPageIndex(pageIndex + 1)}
>
Next
</button>
</div>
);
};

export default PaginationComponent;

+ 5
- 0
components/pagination/swr/PaginationComponentSWR.mock.js Dosyayı Görüntüle

@@ -0,0 +1,5 @@
const base = {};

export const mockPaginationComponentSWRProps = {
base,
};

+ 20
- 0
components/pagination/swr/PaginationComponentSWR.stories.jsx Dosyayı Görüntüle

@@ -0,0 +1,20 @@
import PaginationComponentSWR from './PaginationComponentSWR';
import { mockPaginationComponentSWRProps } from './PaginationComponentSWR.mock';

const obj = {
title: 'pagination/PaginationComponentSWR',
component: PaginationComponentSWR,
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
argTypes: {},
}; //eslint-disable-line

export default obj;
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
const Template = (args) => <PaginationComponentSWR {...args} />;

export const Base = Template.bind({});
// More on args: https://storybook.js.org/docs/react/writing-stories/args

Base.args = {
...mockPaginationComponentSWRProps.base,
};

+ 10
- 0
hooks/use-pagination.js Dosyayı Görüntüle

@@ -0,0 +1,10 @@
import { useQuery } from '@tanstack/react-query';
import { getData } from '../requests/dataRequest';

export const usePagination = (activePage) => {
return useQuery(['randomData', activePage], () => getData(activePage), {
keepPreviousData: true,
refetchOnMount: false,
refetchOnWindowFocus: false,
});
};

+ 15
- 0
hooks/use-swr-with-initial-data.js Dosyayı Görüntüle

@@ -0,0 +1,15 @@
import { useEffect, useRef } from 'react';
import useSWR from 'swr';

export default function useSWRWithFallbackData(key, fetcher, options = {}) {
const hasMounted = useRef(false);

useEffect(() => {
hasMounted.current = true;
}, []);

return useSWR(key, fetcher, {
...options,
fallbackData: hasMounted.current ? undefined : options?.fallbackData,
});
}

+ 6
- 0
next-i18next.config.js Dosyayı Görüntüle

@@ -0,0 +1,6 @@
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
};

+ 5
- 2
next.config.js Dosyayı Görüntüle

@@ -1,7 +1,10 @@
/** @type {import('next').NextConfig} */
const { i18n } = require('./next-i18next.config');

const nextConfig = {
reactStrictMode: true,
swcMinify: true,
}
i18n,
};

module.exports = nextConfig
module.exports = nextConfig;

+ 4
- 0
package.json Dosyayı Görüntüle

@@ -18,16 +18,19 @@
"@mui/codemod": "^5.8.7",
"@mui/icons-material": "^5.8.4",
"@mui/material": "^5.9.2",
"@tanstack/react-query": "^4.0.10",
"bcryptjs": "^2.4.3",
"date-fns": "^2.29.1",
"formik": "^2.2.9",
"mongodb": "^4.8.1",
"next": "12.2.3",
"next-auth": "^4.10.2",
"next-i18next": "^11.3.0",
"prop-types": "^15.8.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"sass": "^1.54.0",
"swr": "^1.3.0",
"yup": "^0.32.11"
},
"devDependencies": {
@@ -44,6 +47,7 @@
"@storybook/manager-webpack5": "^6.5.9",
"@storybook/react": "^6.5.9",
"@storybook/testing-library": "^0.0.13",
"@tanstack/react-query-devtools": "^4.0.10",
"babel-loader": "^8.2.5",
"babel-plugin-import": "^1.13.5",
"cross-env": "^7.0.3",

+ 36
- 4
pages/_app.js Dosyayı Görüntüle

@@ -1,7 +1,39 @@
import '../styles/globals.css'
import {
Hydrate,
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { SessionProvider } from 'next-auth/react';
import { appWithTranslation } from 'next-i18next';
import { useState } from 'react';
import '../styles/globals.css';

function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
function MyApp({ Component, pageProps: { session, ...pageProps } }) {
const [queryClient] = useState(() => new QueryClient());

return (
<QueryClientProvider client={queryClient}>
<Hydrate state={pageProps.dehydratedState}>
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
<ReactQueryDevtools initialIsOpen={false} />
</Hydrate>
</QueryClientProvider>
);
}

export default MyApp
MyApp.getInitialProps = async ({ Component, ctx }) => {
let pageProps = {};

if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}

return {
pageProps,
};
};

export default appWithTranslation(MyApp);

+ 54
- 0
pages/api/data.js Dosyayı Görüntüle

@@ -0,0 +1,54 @@
import { connectToDatabase } from '../../utils/helpers/dbHelpers';

async function handler(req, res) {
if (req.method !== 'GET') {
return;
}

const pageIndex = req.query.page;

if (pageIndex < 1) {
res.status(422).json({
message: 'Page does not exist ',
});
return;
}

const client = await connectToDatabase();
const db = client.db();

const dataCount = await db.collection('randomData').countDocuments();

if ((pageIndex - 1) * 5 >= dataCount) {
res.status(422).json({
message: 'Page does not exist ',
});
client.close();
return;
}

const dataFromDB = await db
.collection('randomData')
.find()
.skip((pageIndex - 1) * 5)
.limit(5)
.toArray();

if (!dataFromDB) {
res.status(422).json({ message: 'No data!' });
client.close();
return;
}

res.status(201).json({
message: 'Created user!',
data: dataFromDB,
dataCount: dataCount,
});

setTimeout(() => {
client.close();
}, 1500);
}

export default handler;

+ 13
- 0
pages/auth/forgot-password/index.js Dosyayı Görüntüle

@@ -1,4 +1,5 @@
import { getSession } from 'next-auth/react';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import ForgotPasswordForm from '../../../components/forms/forgot-password/ForgotPasswordForm';
@@ -18,4 +19,16 @@ const ForgotPasswordPage = () => {
return <ForgotPasswordForm />;
};

export async function getStaticProps({ locale }) {
return {
props: {
...(await serverSideTranslations(locale, [
'forms',
'forgotPass',
'common',
])),
},
};
}

export default ForgotPasswordPage;

+ 9
- 0
pages/auth/index.js Dosyayı Görüntüle

@@ -1,4 +1,5 @@
import { getSession } from 'next-auth/react';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import LoginForm from '../../components/forms/login/LoginForm';
@@ -18,4 +19,12 @@ const AuthPage = () => {
return <LoginForm />;
};

export async function getStaticProps({ locale }) {
return {
props: {
...(await serverSideTranslations(locale, ['forms', 'login'])),
},
};
}

export default AuthPage;

+ 9
- 0
pages/auth/register/index.js Dosyayı Görüntüle

@@ -1,4 +1,5 @@
import { getSession } from 'next-auth/react';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import RegisterForm from '../../../components/forms/register/RegisterForm';
@@ -18,4 +19,12 @@ const RegisterPage = () => {
return <RegisterForm />;
};

export async function getStaticProps({ locale }) {
return {
props: {
...(await serverSideTranslations(locale, ['forms', 'register'])),
},
};
}

export default RegisterPage;

+ 16
- 0
pages/index.js Dosyayı Görüntüle

@@ -1,4 +1,7 @@
import { dehydrate, QueryClient } from '@tanstack/react-query';
import { signOut } from 'next-auth/react';
import PaginationComponentRQ from '../components/pagination/react-query/PaginationComponentRQ';
import { getData } from '../requests/dataRequest';

const Home = () => {
function logoutHandler() {
@@ -8,8 +11,21 @@ const Home = () => {
<>
<h1>Home</h1>
<button onClick={logoutHandler}>Logout</button>
<PaginationComponentRQ></PaginationComponentRQ>
</>
);
};

export async function getServerSideProps() {
const queryClient = new QueryClient();

await queryClient.prefetchQuery(['randomData', 1], () => getData(1));

return {
props: {
dehydratedState: dehydrate(queryClient),
},
};
}

export default Home;

+ 28
- 0
pages/profile/index.js Dosyayı Görüntüle

@@ -0,0 +1,28 @@
import { getSession, useSession } from 'next-auth/react';
import ProfileCard from '../../components/cards/profile-card/ProfileCard';
import { LOGIN_PAGE } from '../../constants/pages';

const ProfilePage = () => {
const { data: session } = useSession();

return <ProfileCard profileData={{ name: session.user.name }} />;
};

export async function getServerSideProps(context) {
const session = await getSession({ req: context.req });

if (!session) {
return {
redirect: {
destination: LOGIN_PAGE,
permanent: false,
},
};
}

return {
props: { session },
};
}

export default ProfilePage;

+ 3
- 0
public/locales/en/common.json Dosyayı Görüntüle

@@ -0,0 +1,3 @@
{
"Back": "Back"
}

+ 4
- 0
public/locales/en/forgotPass.json Dosyayı Görüntüle

@@ -0,0 +1,4 @@
{
"Title": "Forgot password",
"SendBtn": "Send email"
}

+ 7
- 0
public/locales/en/forms.json Dosyayı Görüntüle

@@ -0,0 +1,7 @@
{
"FullName": "Full name",
"Username": "Username",
"Email": "Email",
"Password": "Password",
"ConfirmPassword": "Confirm password"
}

+ 6
- 0
public/locales/en/login.json Dosyayı Görüntüle

@@ -0,0 +1,6 @@
{
"Title": "Login",
"ForgotPassword": "Forgot your password?",
"NoAccount": "Dont have an account?",
"LoginBtn": "Login"
}

+ 6
- 0
public/locales/en/register.json Dosyayı Görüntüle

@@ -0,0 +1,6 @@
{
"Title": "Register",
"ForgotPassword": "Forgot your password?",
"HaveAccount": "Already have an account?",
"RegisterBtn": "Register"
}

+ 2
- 1
requests/apiEndpoints.js Dosyayı Görüntüle

@@ -1,5 +1,6 @@
export default {
account: {
createUser: "/api/auth/signup",
createUser: '/api/auth/signup',
},
data: '/api/data',
};

+ 15
- 0
requests/dataRequest.js Dosyayı Görüntüle

@@ -0,0 +1,15 @@
import apiEndpoints from './apiEndpoints';

export const getData = async (pageIndex) => {
const response = await fetch(
`http://localhost:3000/${apiEndpoints.data}?page=${pageIndex}`
);

const data = await response.json();

if (!response.ok) {
throw new Error(data.message || 'Something went wrong!');
}

return data;
};

+ 102
- 4
yarn.lock Dosyayı Görüntüle

@@ -1073,7 +1073,7 @@
dependencies:
regenerator-runtime "^0.13.2"

"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.18.9", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
version "7.18.9"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a"
integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==
@@ -2854,6 +2854,36 @@
dependencies:
tslib "^2.4.0"

"@tanstack/match-sorter-utils@^8.0.0-alpha.82":
version "8.1.1"
resolved "https://registry.yarnpkg.com/@tanstack/match-sorter-utils/-/match-sorter-utils-8.1.1.tgz#895f407813254a46082a6bbafad9b39b943dc834"
integrity sha512-IdmEekEYxQsoLOR0XQyw3jD1GujBpRRYaGJYQUw1eOT1eUugWxdc7jomh1VQ1EKHcdwDLpLaCz/8y4KraU4T9A==
dependencies:
remove-accents "0.4.2"

"@tanstack/query-core@^4.0.0-beta.1":
version "4.0.10"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.0.10.tgz#cae6f818006616dc72c95c863592f5f68b47548a"
integrity sha512-9LsABpZXkWZHi4P1ozRETEDXQocLAxVzQaIhganxbNuz/uA3PsCAJxJTiQrknG5htLMzOF5MqM9G10e6DCxV1A==

"@tanstack/react-query-devtools@^4.0.10":
version "4.0.10"
resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-4.0.10.tgz#d1b3e5b1917f1c22bcee5830ef7af1ccfc4879f4"
integrity sha512-3J7LLYQjfjTI0DbPo0bA+M3l4kdvYSWAqihpeG1u93WVyZj0OEFviUv+4cK7+k2AVgQJAPMZ5xvtewKxOOFVrw==
dependencies:
"@tanstack/match-sorter-utils" "^8.0.0-alpha.82"
"@types/use-sync-external-store" "^0.0.3"
use-sync-external-store "^1.2.0"

"@tanstack/react-query@^4.0.10":
version "4.0.10"
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.0.10.tgz#92c71a2632c06450d848d4964959bd216cde03c0"
integrity sha512-Wn5QhZUE5wvr6rGClV7KeQIUsdTmYR9mgmMZen7DSRWauHW2UTynFg3Kkf6pw+XlxxOLsyLWwz/Q6q1lSpM3TQ==
dependencies:
"@tanstack/query-core" "^4.0.0-beta.1"
"@types/use-sync-external-store" "^0.0.3"
use-sync-external-store "^1.2.0"

"@testing-library/dom@^8.3.0":
version "8.16.0"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.16.0.tgz#d6fc50250aed17b1035ca1bd64655e342db3936a"
@@ -2948,6 +2978,14 @@
dependencies:
"@types/unist" "*"

"@types/hoist-non-react-statics@^3.3.1":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"

"@types/html-minifier-terser@^5.0.0":
version "5.1.2"
resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz#693b316ad323ea97eed6b38ed1a3cc02b1672b57"
@@ -3124,6 +3162,11 @@
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==

"@types/use-sync-external-store@^0.0.3":
version "0.0.3"
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==

"@types/webidl-conversions@*":
version "6.1.1"
resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz#e33bc8ea812a01f63f90481c666334844b12a09e"
@@ -4555,7 +4598,7 @@ core-js-pure@^3.20.2, core-js-pure@^3.8.1:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.24.1.tgz#8839dde5da545521bf282feb7dc6d0b425f39fd3"
integrity sha512-r1nJk41QLLPyozHUUPmILCEMtMw24NG4oWK6RbsDdjzQgg9ZvrUsPBj1MnG0wXXp1DCDU6j+wUvEmBSrtRbLXg==

core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2:
core-js@^3, core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2:
version "3.24.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.24.1.tgz#cf7724d41724154010a6576b7b57d94c5d66e64f"
integrity sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg==
@@ -6320,7 +6363,7 @@ highlight.js@^10.4.1, highlight.js@~10.7.0:
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==

hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1:
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@@ -6375,6 +6418,13 @@ html-minifier-terser@^6.0.2:
relateurl "^0.2.7"
terser "^5.10.0"

html-parse-stringify@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2"
integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==
dependencies:
void-elements "3.1.0"

html-tags@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961"
@@ -6442,6 +6492,18 @@ husky@^8.0.1:
resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.1.tgz#511cb3e57de3e3190514ae49ed50f6bc3f50b3e9"
integrity sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==

i18next-fs-backend@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/i18next-fs-backend/-/i18next-fs-backend-1.1.4.tgz#d0e9b9ed2fa7a0f11002d82b9fa69c3c3d6482da"
integrity sha512-/MfAGMP0jHonV966uFf9PkWWuDjPYLIcsipnSO3NxpNtAgRUKLTwvm85fEmsF6hGeu0zbZiCQ3W74jwO6K9uXA==

i18next@^21.8.13:
version "21.8.16"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.8.16.tgz#31fe4682e4e2077dbf229a88e5a58b7020e4ddc8"
integrity sha512-acJLCk38YMfEPjBR/1vS13SFY7rBQLs9E5m1tSRnWc9UW3f+SZszgH+NP1fZRA1+O+CdG2eLGGmuUMJW52EwzQ==
dependencies:
"@babel/runtime" "^7.17.2"

[email protected]:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -7874,6 +7936,19 @@ next-auth@^4.10.2:
preact-render-to-string "^5.1.19"
uuid "^8.3.2"

next-i18next@^11.3.0:
version "11.3.0"
resolved "https://registry.yarnpkg.com/next-i18next/-/next-i18next-11.3.0.tgz#bfce51d8df07fb5cd61097423eeb7d744e09ae25"
integrity sha512-xl0oIRtiVrk9ZaWBRUbNk/prva4Htdu59o9rFWzd9ax/KemaDVuTTuBZTQMkmXohUQk/MJ7w1rV/mICL6TzyGw==
dependencies:
"@babel/runtime" "^7.18.6"
"@types/hoist-non-react-statics" "^3.3.1"
core-js "^3"
hoist-non-react-statics "^3.3.2"
i18next "^21.8.13"
i18next-fs-backend "^1.1.4"
react-i18next "^11.18.0"

[email protected]:
version "12.2.3"
resolved "https://registry.yarnpkg.com/next/-/next-12.2.3.tgz#c29d235ce480e589894dfab3120dade25d015a22"
@@ -8937,6 +9012,14 @@ react-fast-compare@^2.0.1:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==

react-i18next@^11.18.0:
version "11.18.3"
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.18.3.tgz#50211810bcc9fdea2d70c8aefdfff5f1eb39a923"
integrity sha512-EttTX31HbqzZymUM3SIrMPuvamfSXFZVsDHm/ZAqoDfTLjhzlwyxqfbDNxcKNAGOi2mjZaXfR7hSNMlvLNpB/g==
dependencies:
"@babel/runtime" "^7.14.5"
html-parse-stringify "^3.0.1"

react-inspector@^5.1.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.1.tgz#58476c78fde05d5055646ed8ec02030af42953c8"
@@ -9242,6 +9325,11 @@ [email protected]:
dependencies:
mdast-squeeze-paragraphs "^4.0.0"

[email protected]:
version "0.4.2"
resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5"
integrity sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==

remove-trailing-separator@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
@@ -10001,6 +10089,11 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==

swr@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/swr/-/swr-1.3.0.tgz#c6531866a35b4db37b38b72c45a63171faf9f4e8"
integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==

symbol.prototype.description@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/symbol.prototype.description/-/symbol.prototype.description-1.0.5.tgz#d30e01263b6020fbbd2d2884a6276ce4d49ab568"
@@ -10538,7 +10631,7 @@ url-loader@^4.1.1:
mime-types "^2.1.27"
schema-utils "^3.0.0"

[email protected]:
[email protected], use-sync-external-store@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
@@ -10641,6 +10734,11 @@ vfile@^4.0.0:
unist-util-stringify-position "^2.0.0"
vfile-message "^2.0.0"

[email protected]:
version "3.1.0"
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"
integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==

walker@^1.0.7, walker@~1.0.5:
version "1.0.8"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f"

Loading…
İptal
Kaydet