diff --git a/package-lock.json b/package-lock.json index 1cc94a5..f757f4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,8 @@ "next-intl": "^4.1.0", "react": "^19.0.0", "react-dom": "^19.0.0", - "react-leaflet": "^5.0.0" + "react-leaflet": "^5.0.0", + "swiper": "^11.2.9" }, "devDependencies": { "@eslint/eslintrc": "^3", @@ -5892,6 +5893,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swiper": { + "version": "11.2.9", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.9.tgz", + "integrity": "sha512-X4lP396wfb85t5GclSlXmZyeDgcV66JK9+HDfqlk+8wJ5Bp85ZMv2fxu9psulsm22dLQxbnN4kADxK8jXTnSuw==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "license": "MIT", + "engines": { + "node": ">= 4.7.0" + } + }, "node_modules/synckit": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.8.tgz", diff --git a/package.json b/package.json index b1eb18d..ac15eb1 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "next-intl": "^4.1.0", "react": "^19.0.0", "react-dom": "^19.0.0", - "react-leaflet": "^5.0.0" + "react-leaflet": "^5.0.0", + "swiper": "^11.2.9" }, "devDependencies": { "@eslint/eslintrc": "^3", diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..95bff76 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/favicon/apple-touch-icon.png b/public/favicon/apple-touch-icon.png new file mode 100644 index 0000000..75aa5f6 Binary files /dev/null and b/public/favicon/apple-touch-icon.png differ diff --git a/public/favicon/favicon-96x96.png b/public/favicon/favicon-96x96.png new file mode 100644 index 0000000..cf83e9a Binary files /dev/null and b/public/favicon/favicon-96x96.png differ diff --git a/public/favicon/favicon.ico b/public/favicon/favicon.ico new file mode 100644 index 0000000..95bff76 Binary files /dev/null and b/public/favicon/favicon.ico differ diff --git a/public/favicon/favicon.svg b/public/favicon/favicon.svg new file mode 100644 index 0000000..79046fa --- /dev/null +++ b/public/favicon/favicon.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/public/favicon/site.webmanifest b/public/favicon/site.webmanifest new file mode 100644 index 0000000..2fd2799 --- /dev/null +++ b/public/favicon/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "Pasargad Bricks", + "short_name": "Pasargad Bricks", + "icons": [ + { + "src": "/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/public/favicon/web-app-manifest-192x192.png b/public/favicon/web-app-manifest-192x192.png new file mode 100644 index 0000000..1e03b69 Binary files /dev/null and b/public/favicon/web-app-manifest-192x192.png differ diff --git a/public/favicon/web-app-manifest-512x512.png b/public/favicon/web-app-manifest-512x512.png new file mode 100644 index 0000000..146778e Binary files /dev/null and b/public/favicon/web-app-manifest-512x512.png differ diff --git a/src/app/[locale]/blog/page.tsx b/src/app/[locale]/blog/page.tsx index c1bbae2..7a89924 100644 --- a/src/app/[locale]/blog/page.tsx +++ b/src/app/[locale]/blog/page.tsx @@ -18,7 +18,9 @@ export async function generateMetadata({ params }: { params: IPageParams }) { export default async function Blog({ params }: { params: IPageParams }) { const paramsData = await params; - const t = await getTranslations({ locale: paramsData.locale }); + const { locale } = paramsData; + + const t = await getTranslations({ locale }); const { data: posts, pagination } = await getPosts(); @@ -28,7 +30,9 @@ export default async function Blog({ params }: { params: IPageParams }) { title={t('pages_blog_title')} imageSrc={images.blogBanner.src} /> - +
+ +
); } diff --git a/src/app/[locale]/favicon.ico b/src/app/[locale]/favicon.ico deleted file mode 100644 index 718d6fe..0000000 Binary files a/src/app/[locale]/favicon.ico and /dev/null differ diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 1a9bcaa..a5c0b2a 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -57,7 +57,22 @@ export default async function RootLayout({ - + {/* */} + + + + + + diff --git a/src/app/[locale]/projects/page.tsx b/src/app/[locale]/projects/page.tsx index aa47922..789be68 100644 --- a/src/app/[locale]/projects/page.tsx +++ b/src/app/[locale]/projects/page.tsx @@ -3,6 +3,7 @@ import routeFactory from '@/assets/constants/routeFactory'; import images from '@/assets/images/images'; import InnerPageBanner from '@/components/layout/innerPages/banner'; import SectionTitle from '@/components/layout/sectionTitle'; +import ProjectsGrid from '@/components/pages/project/ProjectGrid'; import ProjectsGridView from '@/components/pages/project/projectGridView'; import Button from '@/components/uikit/button'; import { IPageParams } from '@/models/layout'; @@ -40,7 +41,7 @@ export default async function ProjectsPage({

{t('page_projects_description')}

- diff --git a/src/app/favicon.ico b/src/app/favicon.ico deleted file mode 100644 index 718d6fe..0000000 Binary files a/src/app/favicon.ico and /dev/null differ diff --git a/src/components/pages/blog/PostThumb.tsx b/src/components/pages/blog/PostThumb.tsx new file mode 100644 index 0000000..7c54d29 --- /dev/null +++ b/src/components/pages/blog/PostThumb.tsx @@ -0,0 +1,46 @@ +import { IPostThumbResponseData } from '@/app/api/blog/data'; +import routeFactory from '@/assets/constants/routeFactory'; +import Button from '@/components/uikit/button'; +import { TLocales } from '@/models/layout'; +import Image from 'next/image'; +import Link from 'next/link'; +import { useTranslations } from 'use-intl'; + +interface Props { + post: IPostThumbResponseData; + locale: TLocales; +} + +const PostThumb = ({ post, locale }: Props) => { + const t = useTranslations(); + const routes = routeFactory(t, locale); + return ( +
+
+ {post.title} + +
+ +
+
+ +

{post.title}

+ +
+ ); +}; + +export default PostThumb; diff --git a/src/components/pages/blog/PostsGrid.tsx b/src/components/pages/blog/PostsGrid.tsx index a84edd7..9cd7f1c 100644 --- a/src/components/pages/blog/PostsGrid.tsx +++ b/src/components/pages/blog/PostsGrid.tsx @@ -2,11 +2,9 @@ import { useState } from 'react'; import Pagination from '@/components/layout/pagination'; - import { getPosts } from '@/services/blog'; import { IPostThumbResponseData } from '@/app/api/blog/data'; import { IPagination } from '@/models/response'; -import routeFactory from '@/assets/constants/routeFactory'; import { useParams } from 'next/navigation'; import { TLocales } from '@/models/layout'; import { useTranslations } from 'next-intl'; @@ -24,8 +22,6 @@ export default function PostsGrid({ const t = useTranslations(); const { locale } = useParams(); - const routes = routeFactory(t, locale as TLocales); - const [posts, setPosts] = useState(initialPosts); const [pagination, setPagination] = useState(initialPagination); @@ -34,6 +30,9 @@ export default function PostsGrid({ .then((res) => { setPosts(res.data); setPagination(res.pagination); + document + .getElementById('postList') + ?.scrollIntoView({ behavior: 'smooth', block: 'start' }); }) .catch((error) => { console.error('Failed to fetch posts:', error); diff --git a/src/components/pages/blog/PostsGridView.tsx b/src/components/pages/blog/PostsGridView.tsx index 5d79c24..994d232 100644 --- a/src/components/pages/blog/PostsGridView.tsx +++ b/src/components/pages/blog/PostsGridView.tsx @@ -1,52 +1,25 @@ +'use client'; + import { IPostThumbResponseData } from '@/app/api/blog/data'; import routeFactory from '@/assets/constants/routeFactory'; -import Button from '@/components/uikit/button'; import { TLocales } from '@/models/layout'; -import { getTranslations } from 'next-intl/server'; -import Image from 'next/image'; -import Link from 'next/link'; +import PostThumb from './PostThumb'; +import { useTranslations } from 'next-intl'; -export default async function PostsGridView({ +export default function PostsGridView({ posts, locale, }: { posts: IPostThumbResponseData[]; locale: TLocales; }) { - const t = await getTranslations({ locale }); + const t = useTranslations(); const routes = routeFactory(t, locale); return ( <> {posts.map((post) => ( -
-
- {post.title} - -
- -
-
- -

{post.title}

- -
+ ))} ); diff --git a/src/components/pages/blog/postsGridViewSlider.tsx b/src/components/pages/blog/postsGridViewSlider.tsx new file mode 100644 index 0000000..69d3bfd --- /dev/null +++ b/src/components/pages/blog/postsGridViewSlider.tsx @@ -0,0 +1,41 @@ +'use client'; + +import { Swiper, SwiperSlide } from 'swiper/react'; +import { FreeMode } from 'swiper/modules'; +import 'swiper/css'; +import 'swiper/css/free-mode'; +import { IPostThumbResponseData } from '@/app/api/blog/data'; +import { useTranslations } from 'use-intl'; +import routeFactory from '@/assets/constants/routeFactory'; +import { TLocales } from '@/models/layout'; +import PostThumb from './PostThumb'; + +interface Props { + posts: IPostThumbResponseData[]; + locale: TLocales; +} + +export default function PostsGridViewSlider({ posts, locale }: Props) { + const t = useTranslations(); + const routes = routeFactory(t, locale); + return ( +
+ + {posts.map((post) => ( + + + + ))} + +
+ ); +} diff --git a/src/components/pages/home/HomePageBlog.tsx b/src/components/pages/home/HomePageBlog.tsx index 73da452..14d5a08 100644 --- a/src/components/pages/home/HomePageBlog.tsx +++ b/src/components/pages/home/HomePageBlog.tsx @@ -4,7 +4,7 @@ import { TLocales } from '@/models/layout'; import Button from '@/components/uikit/button'; import routeFactory from '@/assets/constants/routeFactory'; import { getPosts } from '@/services/blog'; -import PostsGridView from '../blog/PostsGridView'; +import PostsGridViewSlider from '../blog/postsGridViewSlider'; interface Props { locale: TLocales; className?: string; @@ -38,8 +38,11 @@ export default async function HomePageBlog({ locale, className }: Props) { -
- +
+
+
+ +
- - - - - -

{project.title}

- - - ))} +
+
+ +
+
); } diff --git a/src/components/pages/project/ProjectThumb.tsx b/src/components/pages/project/ProjectThumb.tsx new file mode 100644 index 0000000..749b247 --- /dev/null +++ b/src/components/pages/project/ProjectThumb.tsx @@ -0,0 +1,43 @@ +import Image from 'next/image'; +import Link from 'next/link'; +import Button from '@/components/uikit/button'; +import { useTranslations } from 'next-intl'; +import routeFactory from '@/assets/constants/routeFactory'; +import { IProjectThumbResponseData } from '@/app/api/projects/data'; +import { TLocales } from '@/models/layout'; + +interface Props { + project: IProjectThumbResponseData; + locale: TLocales; +} + +const ProjectThumb = ({ project, locale }: Props) => { + const t = useTranslations(); + const routes = routeFactory(t, locale); + return ( +
+
+ {project.title} +
+ +
+
+ + +

{project.title}

+ +
+ ); +}; + +export default ProjectThumb; diff --git a/src/components/pages/project/projectGridView.tsx b/src/components/pages/project/projectGridView.tsx index d1628e4..1495891 100644 --- a/src/components/pages/project/projectGridView.tsx +++ b/src/components/pages/project/projectGridView.tsx @@ -1,37 +1,20 @@ 'use client'; -import { getProjects } from '@/services/projects'; -import { IProjectGridViewProps } from './project'; -import ProjectsGrid from './ProjectGrid'; -import Pagination from '@/components/layout/pagination'; -import { useState } from 'react'; +import ProjectThumb from './ProjectThumb'; +import { IProjectThumbResponseData } from '@/app/api/projects/data'; +import { TLocales } from '@/models/layout'; -export default function ProjectsGridView({ - initialProjects, - initialPagination, -}: IProjectGridViewProps) { - const [projects, setProjects] = useState(initialProjects); - const [pagination, setPagination] = useState(initialPagination); - - const fetchPage = (page: number) => { - getProjects(page) - .then((res) => { - setProjects(res.data); - setPagination(res.pagination); - - document - .getElementById('projectList') - ?.scrollIntoView({ behavior: 'smooth', block: 'start' }); - }) - .catch((error) => { - console.error('Failed to fetch Projects:', error); - }); - }; +interface Props { + projects: IProjectThumbResponseData[]; + locale: TLocales; +} +export default function ProjectsGridView({ projects, locale }: Props) { return ( <> - {projects?.length ? : <>} - + {projects?.map((project) => ( + + ))} ); } diff --git a/src/components/pages/project/projectsGridSlider.tsx b/src/components/pages/project/projectsGridSlider.tsx new file mode 100644 index 0000000..5074ee8 --- /dev/null +++ b/src/components/pages/project/projectsGridSlider.tsx @@ -0,0 +1,40 @@ +'use client'; + +import { Swiper, SwiperSlide } from 'swiper/react'; +import { FreeMode } from 'swiper/modules'; +import 'swiper/css'; +import 'swiper/css/free-mode'; +import ProjectThumb from './ProjectThumb'; +import { TLocales } from '@/models/layout'; +import { IProjectThumbResponseData } from '@/app/api/projects/data'; + +export default function ProjectsGridSlider({ + projects, + locale, + className = '', +}: { + projects: IProjectThumbResponseData[]; + locale: TLocales; + className?: string; +}) { + return ( +
+ + {projects.map((project) => ( + + + + ))} + +
+ ); +}