Skip to content

Commit

Permalink
add Link component for i18n, add category ui, add translate, add gith…
Browse files Browse the repository at this point in the history
…ubPath for code mdx
  • Loading branch information
MarkMelior committed Jul 14, 2024
1 parent c8d4ade commit d406be6
Show file tree
Hide file tree
Showing 33 changed files with 260 additions and 197 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

- [middleware.ts](/middleware.ts) - основной функционал работы i18n
- [getLang()](src/shared/config/i18n/get-lang.ts) - возвращает выбранный язык `en | ru`
- [useLang()](src/shared/config/i18n/use-lang.ts) - как `getLang()`, только для клиентского компонента
- [getDictionary()](src/shared/config/i18n/dictionaries.ts) - возвращает объект с переводами `ключ-значение`
- [useDictionary()](src/shared/config/i18n/use-dictionary.ts) - как `getDictionary()`, только для клиентского компонента
- [type Dictionary](src/shared/config/i18n/dictionaries.ts)
- [/dictionary](src/shared/config/i18n/dictionaries/) - директория с json файлами переводов

Expand Down
29 changes: 20 additions & 9 deletions app/[lang]/projects/[category]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getProjectsByCategory } from '@/entity/project';
import { Link } from '@/shared/config';
import { Header } from '@/widgets';
import { Metadata } from 'next';
import Link from 'next/link';

export type ProjectCategoryPageProps = {
params: { category: string };
Expand All @@ -13,16 +14,26 @@ export default async function ProjectCategoryPage({

return (
<>
<h1>{category.title}</h1>
<Header
note='Категория'
title={category.title}
description='Здесь находятся все проекты из данной категории'
/>

<p>Projects:</p>
{projects.map((project) => (
<>
<Link href={project.link} key={project.title}>
{project.title} - {project.description}
<div className='grid grid-cols-2 gap-4'>
{projects.map((project) => (
<Link
href={project.link}
key={project.title}
className='px-6 py-4 bg-default-100 hover:bg-default-100/50 border border-default-200 hover:border-default-300 rounded-md flex flex-col gap-2 transition active:scale-[0.98]'
>
{project.title}
<span className='text-default-600 text-sm'>
{project.description}
</span>
</Link>
</>
))}
))}
</div>
</>
);
}
Expand Down
14 changes: 11 additions & 3 deletions middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function middleware(request: NextRequest) {
pathname === `/${i18n.defaultLocale}`
) {
// The incoming request is for /en/whatever, so we'll reDIRECT to /whatever
return NextResponse.redirect(
const response = NextResponse.redirect(
new URL(
pathname.replace(
`/${i18n.defaultLocale}`,
Expand All @@ -36,6 +36,8 @@ export function middleware(request: NextRequest) {
headers: requestHeaders,
},
);
// response.cookies.set('NEXT_LOCALE', i18n.defaultLocale);
return response;
}

const pathnameIsMissingLocale = i18n.locales.every(
Expand All @@ -46,7 +48,7 @@ export function middleware(request: NextRequest) {
if (pathnameIsMissingLocale) {
// Now for EITHER /en or /nl (for example) we're going to tell Next.js that the request is for /en/whatever
// or /nl/whatever, and then reWRITE the request to that it is handled properly.
return NextResponse.rewrite(
const response = NextResponse.rewrite(
new URL(
`/${i18n.defaultLocale}${pathname}${request.nextUrl.search}`,
request.nextUrl.href,
Expand All @@ -57,13 +59,19 @@ export function middleware(request: NextRequest) {
},
},
);
// response.cookies.set('NEXT_LOCALE', i18n.defaultLocale);
return response;
}

return NextResponse.next({
// const lang = (pathname.split('/')[1] as Locale) || i18n.defaultLocale;

const response = NextResponse.next({
request: {
headers: requestHeaders,
},
});
// response.cookies.set('NEXT_LOCALE', lang);
return response;
}

export const config = {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
"framer-motion": "^11.2.13",
"gray-matter": "^4.0.3",
"jose": "^5.6.3",
"js-cookie": "^3.0.5",
"next": "14.2.4",
"next-mdx-remote": "^5.0.0",
"next-themes": "^0.3.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.2.1",
"react-syntax-highlighter": "^15.5.0",
"rehype-mdx-code-props": "^3.0.1",
"remark-gfm": "^4.0.0",
"tailwind-merge": "^2.4.0",
"unist-util-visit": "^5.0.0",
Expand All @@ -37,6 +37,7 @@
"devDependencies": {
"@tailwindcss/typography": "^0.5.13",
"@types/bcryptjs": "^2.4.6",
"@types/js-cookie": "^3.0.6",
"@types/mdx": "^2.0.13",
"@types/node": "^20.14.10",
"@types/react": "^18.3.3",
Expand Down
59 changes: 15 additions & 44 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion projects/best-practice/app-router-auth/en.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Getting user data: `const user = await getUser();`. It's very simple :)

test))

```TypeScript filename="src/features/auth/api/jwt.ts"
```TypeScript filename="features/auth/api/jwt.ts" githubPath="src/features/auth/api/jwt.ts"
import { SignJWT, jwtVerify } from 'jose';
import { SessionPayload } from '../types/definitions';

Expand Down
7 changes: 5 additions & 2 deletions projects/best-practice/app-router-auth/examples/auth.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { LogoutButton } from '@/features';
import { getDictionary } from '@/shared/config';
import { CodeBlock } from '@/shared/ui';
import { Card } from '@nextui-org/react';
import { FiUserCheck } from 'react-icons/fi';
Expand All @@ -7,6 +8,7 @@ import { FormLoginExample } from './ui/form-login';

export const AuthExample = async () => {
const user = await getUserExample();
const dict = await getDictionary();

return (
<>
Expand All @@ -15,16 +17,17 @@ export const AuthExample = async () => {
<div className='flex gap-3 items-center'>
<FiUserCheck size={18} className='text-default-400' />
<p className='text-sm'>
You have successfully logged in as an {user?.name}
{`${dict.ui['auth-logged']} ${user?.name}`}
</p>
</div>
<LogoutButton />
<LogoutButton dict={dict.ui} />
</Card>
)}

<div className='grid sm:grid-cols-2 gap-12'>
<FormLoginExample className='w-full' isDisabled={Boolean(user)} />
<CodeBlock
dict={dict.ui}
text={
'# Administrator:\n- Username: admin\n- Password: pass\n\n# User:\n- Username: user\n- Password: pass'
}
Expand Down
2 changes: 1 addition & 1 deletion projects/best-practice/app-router-auth/ru.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ tags: ['TypeScript', 'Cookie', 'SSR', 'Prisma']

тест))

```TypeScript filename="src/features/auth/api/jwt.ts"
```TypeScript filename="features/auth/api/jwt.ts" githubPath="src/features/auth/api/jwt.ts"
import { SignJWT, jwtVerify } from 'jose';
import { SessionPayload } from '../types/definitions';

Expand Down
27 changes: 0 additions & 27 deletions src/entity/project/model/services/get-projects-by-category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,3 @@ export async function getProjectsByCategory(
projects: projectMetadata,
};
}

// export async function getProjectsByCategory(
// category: string,
// ): Promise<ProjectsByCategoryResponse> {
// const dir = path.join(process.cwd(), 'projects', category);
// const indexFile = path.join(dir, 'index.mdx');
// const categoryMetadata = (await getMetadata(indexFile)) as CategoryMetadata;

// const projectDirs = await fs.readdir(dir, { withFileTypes: true });
// const projectMetadata = await Promise.all(
// projectDirs
// .filter((dirent) => dirent.isDirectory())
// .map(async (dirent) => {
// const projectFile = path.join(dir, dirent.name, 'page.mdx');
// const projectMetadata = await getMetadata(projectFile);
// return {
// ...projectMetadata,
// link: `/projects/${category}/${dirent.name}`,
// } as ProjectMetadata & { link: string };
// }),
// );

// return {
// category: categoryMetadata,
// projects: projectMetadata,
// };
// }
5 changes: 3 additions & 2 deletions src/features/auth/ui/logout-button/logout-button.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'use client';

import { Dictionary } from '@/shared/config';
import { Button } from '@nextui-org/react';
import { RxExit } from 'react-icons/rx';
import { logout } from '../../services/logout';

export const LogoutButton = () => {
export const LogoutButton = ({ dict }: { dict: Dictionary['ui'] }) => {
return (
<Button
startContent={<RxExit size={18} />}
Expand All @@ -13,7 +14,7 @@ export const LogoutButton = () => {
size='sm'
onClick={async () => await logout()}
>
Logout
{dict['auth-logout']}
</Button>
);
};
12 changes: 0 additions & 12 deletions src/features/locale-switcher/locale-switcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,5 @@ export const LocaleSwitcher = ({ dict }: { dict: Dictionary['ui'] }) => {
</DropdownSection>
</DropdownMenu>
</Dropdown>
// <Tooltip content='Change language' placement='bottom' offset={15}>
// <Button
// as={Link}
// href={isDefaultLang ? '/en' : '/ru'}
// variant='light'
// isIconOnly
// color='primary'
// >
// <HiOutlineLanguage size={18} />
// {/* {isDefaultLang ? '🇷🇺' : '🇬🇧'} */}
// </Button>
// </Tooltip>
);
};
Loading

0 comments on commit d406be6

Please sign in to comment.