diff --git a/next.config.mjs b/next.config.mjs
index 9e682c8..0104334 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -6,8 +6,8 @@ const nextConfig = {
images: {
remotePatterns: [
{
- protocol: "https",
- hostname: "**",
+ protocol: "http",
+ hostname: "***",
},
],
},
diff --git a/src/app/[locale]/news/page.tsx b/src/app/[locale]/news/page.tsx
new file mode 100644
index 0000000..6078f56
--- /dev/null
+++ b/src/app/[locale]/news/page.tsx
@@ -0,0 +1,22 @@
+import { Container, Title } from "@/shared/ui";
+import NewsList from "@/widgets/NewsList/NewsList";
+import React from "react";
+
+const News = ({
+ searchParams,
+}: {
+ searchParams: {
+ ["страница-новостей"]: string;
+ };
+}) => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default News;
diff --git a/src/entities/NewsCard.tsx b/src/entities/NewsCard.tsx
new file mode 100644
index 0000000..b8ac8f7
--- /dev/null
+++ b/src/entities/NewsCard.tsx
@@ -0,0 +1,50 @@
+import { Title } from "@/shared/ui";
+import Image, { StaticImageData } from "next/image";
+
+interface INewsCard {
+ id: number;
+ image: StaticImageData | string;
+ title: string;
+ content: string;
+ date: string;
+}
+const NewsCard = ({ id, image, title, content, date }: INewsCard) => {
+ const sliceTitle = (title: string) => {
+ if (title.length > 35) {
+ return `${title.slice(0, 35)}...`;
+ }
+
+ return title;
+ };
+ const sliceDescription = (content: string) => {
+ if (content.length > 65) {
+ return `${content.slice(0, 65)}...`;
+ }
+
+ return content;
+ };
+ const sliceDate = (date: string) => {
+ return `${date.slice(8, 10)}/${date.slice(5, 7)}/${date.slice(0, 4)}`;
+ };
+ return (
+
+
+
+
+ {sliceDescription(content)}
+
+
{sliceDate(date)}
+
+ );
+};
+
+export default NewsCard;
diff --git a/src/shared/types/news-type.ts b/src/shared/types/news-type.ts
new file mode 100644
index 0000000..ca44e80
--- /dev/null
+++ b/src/shared/types/news-type.ts
@@ -0,0 +1,13 @@
+import { IList } from "./list-type";
+
+export interface INews {
+ id: number;
+ title: string;
+ content: string;
+ image: string;
+ created_at: string;
+}
+
+export interface INewsList extends IList {
+ results: INews[];
+}
diff --git a/src/widgets/NewsList/NewsList.tsx b/src/widgets/NewsList/NewsList.tsx
new file mode 100644
index 0000000..a51a633
--- /dev/null
+++ b/src/widgets/NewsList/NewsList.tsx
@@ -0,0 +1,56 @@
+"use client";
+
+import { useEffect, useState } from "react";
+import { useNewsStore } from "./newsStore";
+import NewsCard from "@/entities/NewsCard";
+import Pagination from "@/features/Pagination/Pagination";
+
+interface INewsListProps {
+ searchParams: {
+ ["страница-новостей"]: string;
+ };
+}
+
+const NewsList: React.FC = ({
+ searchParams,
+}: INewsListProps) => {
+ const [activePage, setActivePage] = useState(
+ +searchParams["страница-новостей"] || 1
+ );
+ const { data: news, getNews, isLoading, error } = useNewsStore();
+
+ useEffect(() => {
+ getNews(activePage);
+ }, []);
+ return (
+
+
+ {news.results.map((news) => (
+ -
+
+
+ ))}
+
+
+
+
+ );
+};
+
+export default NewsList;
diff --git a/src/widgets/NewsList/newsStore.ts b/src/widgets/NewsList/newsStore.ts
new file mode 100644
index 0000000..c39828f
--- /dev/null
+++ b/src/widgets/NewsList/newsStore.ts
@@ -0,0 +1,38 @@
+import { apiInstance } from "@/shared/config/apiConfig";
+import { IFetch } from "@/shared/types/fetch-type";
+import { INewsList } from "@/shared/types/news-type";
+import { AxiosError } from "axios";
+import { create } from "zustand";
+
+interface useNewsStore extends IFetch {
+ data: INewsList;
+ getNews: (page: number) => void;
+}
+
+export const useNewsStore = create((set) => ({
+ data: {
+ count: 0,
+ previous: null,
+ next: null,
+ results: [],
+ },
+ error: "",
+ isLoading: false,
+ getNews: async (page: number) => {
+ try {
+ set({ isLoading: true });
+
+ const res = await apiInstance.get(`/news/`);
+
+ set({ data: res.data });
+ } catch (error: unknown) {
+ if (error instanceof AxiosError) {
+ set({ error: error.message });
+ } else {
+ set({ error: "An error ocured" });
+ }
+ } finally {
+ set({ isLoading: false });
+ }
+ },
+}));