Browse Source

blogs page connected to api

main
sina_sajjadi 2 months ago
parent
commit
6ea3e9af44
  1. 22
      src/app/blog/Card12.tsx
  2. 18
      src/app/blog/Card13.tsx
  3. 19
      src/app/blog/SectionMagazine5.tsx
  4. 108
      src/app/blog/[...slug]/page.tsx
  5. 4
      src/app/blog/page.tsx
  6. 20
      src/components/PostCardMeta.tsx
  7. 2
      src/data/jsons/__posts.json
  8. 39
      src/data/types.ts

22
src/app/blog/Card12.tsx

@ -1,5 +1,5 @@
import React, { FC } from "react";
import { PostDataType } from "@/data/types";
import { Blog } from "@/data/types";
import PostCardMeta from "@/components/PostCardMeta";
import PostTypeFeaturedIcon from "@/components/PostTypeFeaturedIcon";
import SocialsShare from "@/shared/SocialsShare";
@ -9,31 +9,31 @@ import Image from "next/image";
export interface Card12Props {
className?: string;
post?: PostDataType;
post?: Blog;
}
const Card12: FC<Card12Props> = ({
className = "h-full",
post = DEMO_POSTS[0],
}) => {
const { title, href, featuredImage, desc, postType } = post;
console.log(post);
return (
<div className={`nc-Card12 group relative flex flex-col ${className}`}>
<Link
href={href}
href={`blog/${post?.slug}`}
className="block flex-shrink-0 flex-grow relative w-full h-0 aspect-w-4 aspect-h-3 rounded-3xl overflow-hidden"
>
<Image
fill
src={featuredImage}
alt={title}
src={post?.cover}
alt={post?.title}
sizes="(max-width: 768px) 100vw, 400px"
/>
<span>
<PostTypeFeaturedIcon
className="absolute bottom-2 left-2"
postType={postType}
postType={"standard"}
wrapSize="w-8 h-8"
iconSize="w-4 h-4"
/>
@ -46,12 +46,12 @@ const Card12: FC<Card12Props> = ({
<h2
className={`nc-card-title block font-semibold text-neutral-900 dark:text-neutral-100 transition-colors text-lg sm:text-2xl`}
>
<Link href={href} className="line-clamp-2" title={title}>
{title}
<Link href={`blog/${post?.slug}`} className="line-clamp-2" title={post?.title}>
{post?.title}
</Link>
</h2>
<span className="hidden sm:block mt-4 text-neutral-500 dark:text-neutral-400">
<span className="line-clamp-2"> {desc}</span>
<span className="line-clamp-2"> {post?.summary}</span>
</span>
<PostCardMeta className="mt-5" meta={post} />
</div>

18
src/app/blog/Card13.tsx

@ -11,21 +11,21 @@ export interface Card13Props {
}
const Card13: FC<Card13Props> = ({ className = "", post }) => {
const { title, href, desc, featuredImage, date, postType } = post;
return (
<div className={`nc-Card13 relative flex ${className}`} data-nc-id="Card13">
<div className="flex flex-col h-full py-2">
<h2 className={`nc-card-title block font-semibold text-base`}>
<Link href={href} className="line-clamp-2" title={title}>
{title}
<Link href={`blog/${post?.slug}`} className="line-clamp-2" title={post?.title}>
{post?.title}
</Link>
</h2>
<span className="hidden sm:block my-3 text-neutral-500 dark:text-neutral-400 ">
<span className="line-clamp-2"> {desc}</span>
<span className="line-clamp-2"> {post?.summary}</span>
</span>
<span className="mt-4 block sm:hidden text-sm text-neutral-500 ">
{date}
{post?.date}
</span>
<div className="mt-auto hidden sm:block">
<PostCardMeta meta={{ ...post }} />
@ -33,19 +33,19 @@ const Card13: FC<Card13Props> = ({ className = "", post }) => {
</div>
<Link
href={href}
href={`blog/${post?.slug}`}
className={`block relative h-full flex-shrink-0 w-2/5 sm:w-1/3 ml-3 sm:ml-5`}
>
<Image
fill
className="object-cover rounded-xl sm:rounded-3xl"
src={featuredImage}
alt={title}
src={post?.cover}
alt={post?.title}
sizes="(max-width: 768px) 100vw, 400px"
/>
<PostTypeFeaturedIcon
className="absolute bottom-2 left-2"
postType={postType}
postType={"standard"}
wrapSize="w-8 h-8"
iconSize="w-4 h-4"
/>

19
src/app/blog/SectionMagazine5.tsx

@ -1,13 +1,22 @@
import React, { FC } from "react";
"use client"
import React, { FC, useEffect, useState } from "react";
import { PostDataType } from "@/data/types";
import Card12 from "./Card12";
import Card13 from "./Card13";
import axiosInstance from "@/components/api/axios";
const SectionMagazine5 = () => {
export interface SectionMagazine5Props {
posts: PostDataType[];
}
const [posts , setPosts] = useState([])
const SectionMagazine5: FC<SectionMagazine5Props> = ({ posts }) => {
useEffect(()=>{
axiosInstance.get("/api/blogs/")
.then((response)=>{
setPosts(response.data.results);
})
} , [])
return (
<div className="nc-SectionMagazine5">
<div className="grid lg:grid-cols-2 gap-6 md:gap-8">

108
src/app/blog/[...slug]/page.tsx

@ -1,4 +1,6 @@
import React from "react";
"use client"
import React, { useEffect, useState } from "react";
import { DEMO_POSTS } from "@/data/posts";
import { PostDataType } from "@/data/types";
import Avatar from "@/shared/Avatar";
@ -14,6 +16,7 @@ import Link from "next/link";
import { Route } from "@/routers/types";
import { BiLike , BiDislike } from "react-icons/bi";
import Survey from "./Survey";
import axiosInstance from "@/components/api/axios";
const Page = ({
params,
@ -22,7 +25,21 @@ const Page = ({
params: { stepIndex: string };
searchParams?: { [key: string]: string | string[] | undefined };
}) => {
const [ blog , setBlog] = useState()
useEffect(()=>{
axiosInstance.get(`/api/blogs/${params.slug[0]}/`)
.then((response)=>{
setBlog(response.data);
})
})
const renderHeader = () => {
return (
<header className="container rounded-xl">
<div className="max-w-screen-md mx-auto space-y-5">
@ -31,13 +48,13 @@ const Page = ({
className=" text-neutral-900 font-semibold text-3xl md:text-4xl md:!leading-[120%] lg:text-4xl dark:text-neutral-100 max-w-4xl "
title="Quiet ingenuity: 120,000 lunches and counting"
>
Keep up the spirit of the desire to travel around the world
{blog?.title}
</h1>
<span className="block text-base text-neutral-500 md:text-lg dark:text-neutral-400 pb-1">
{/* <span className="block text-base text-neutral-500 md:text-lg dark:text-neutral-400 pb-1">
Were an online magazine dedicated to covering the best in
international product design. We started as a little blog back in
2002 covering student work and over time
</span>
</span> */}
<div className="w-full border-b border-neutral-100 dark:border-neutral-800"></div>
<div className="flex flex-col items-baseline sm:flex-row sm:justify-between">
@ -77,86 +94,7 @@ const Page = ({
<div
id="single-entry-content"
className="prose dark:prose-invert prose-sm !max-w-screen-md sm:prose lg:prose-lg mx-auto dark:prose-dark"
>
<p>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Iure vel
officiis ipsum placeat itaque neque dolorem modi perspiciatis dolor
distinctio veritatis sapiente, minima corrupti dolores necessitatibus
suscipit accusantium dignissimos culpa cumque.
</p>
<p>
It is a long established fact that a <strong>reader</strong> will be
distracted by the readable content of a page when looking at its{" "}
<strong>layout</strong>. The point of using Lorem Ipsum is that it has
a more-or-less normal{" "}
<a href="/#" target="_blank" rel="noopener noreferrer">
distribution of letters.
</a>{" "}
</p>
<ol>
<li>We want everything to look good out of the box.</li>
<li>
{` Really just the first reason, that's the whole point of the plugin.`}
</li>
<li>
{` Here's a third pretend reason though a list with three items looks
more realistic than a list with two items.`}
</li>
</ol>
<h3>Typography should be easy</h3>
<p>
{`So that's a header for you — with any luck if we've done our job
correctly that will look pretty reasonable.`}
</p>
<p>Something a wise person once told me about typography is:</p>
<blockquote>
<p>
{` Typography is pretty important if you don't want your stuff to look
like trash. Make it good then it won't be bad.`}
</p>
</blockquote>
<p>
{` It's probably important that images look okay here by default as well:`}
</p>
<figure>
<Image src={travelhero2Image} alt="blog" className="rounded-2xl" />
<figcaption>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Iure vel
officiis ipsum placeat itaque neque dolorem modi perspiciatis dolor
distinctio veritatis sapiente
</figcaption>
</figure>
<p>
{` Now I'm going to show you an example of an unordered list to make sure
that looks good, too:`}
</p>
<ul>
<li>So here is the first item in this list.</li>
<li>{`In this example we're keeping the items short.`}</li>
<li>{`Later, we'll use longer, more complex list items.`}</li>
</ul>
<p>{`And that's the end of this section.`}</p>
<h2>Code should look okay by default.</h2>
<p>
I think most people are going to use{" "}
<a href="https://highlightjs.org/">highlight.js</a> or{" "}
<a href="https://prismjs.com/">Prism</a>{" "}
{`or something if they want to
style their code blocks but it wouldn't hurt to make them look`}{" "}
<em>okay</em> out of the box, even with no syntax highlighting.
</p>
<p>
{` What I've written here is probably long enough, but adding this final
sentence can't hurt.`}
</p>
<p>Hopefully that looks good enough to you.</p>
<h3>We still need to think about stacked headings though.</h3>
<p>
Phew, with any luck we have styled the headings above this text and
they look pretty good.
</p>
><div dangerouslySetInnerHTML={{ __html: blog?.content }} />
</div>
);
};
@ -269,7 +207,7 @@ const Page = ({
<div className="nc-PageSingle pt-8 lg:pt-16 ">
{renderHeader()}
<div className="container my-10 sm:my-12 ">
<Image className="w-full rounded-xl" src={travelhero2Image} alt="" />
{/* <Image className="w-full rounded-xl" src={blog?.cover} fill alt="" /> */}
</div>
<div className="nc-SingleContent container space-y-10">

4
src/app/blog/page.tsx

@ -7,10 +7,8 @@ import BgGlassmorphism from "@/components/BgGlassmorphism";
import SectionSubscribe2 from "@/components/SectionSubscribe2";
// DEMO DATA
const POSTS = DEMO_POSTS;
// DEMO POST FOR MAGAZINE SECTION
const MAGAZINE1_POSTS = POSTS.filter((_, i) => i >= 0 && i < 8);
//
const BlogPage: React.FC = () => {
@ -19,7 +17,7 @@ const BlogPage: React.FC = () => {
<BgGlassmorphism />
<div className="container relative">
<div className="pt-12 pb-16 lg:pb-28">
<SectionMagazine5 posts={MAGAZINE1_POSTS} />
<SectionMagazine5 />
</div>
{/*
<SectionAds />

20
src/components/PostCardMeta.tsx

@ -5,7 +5,7 @@ import Link from "next/link";
export interface PostCardMetaProps {
className?: string;
meta: Pick<PostDataType, "date" | "author">;
meta: Pick<PostDataType, "date" | "author" | "created_at">;
hiddenAvatar?: boolean;
size?: "large" | "normal";
}
@ -16,7 +16,7 @@ const PostCardMeta: FC<PostCardMetaProps> = ({
hiddenAvatar = false,
size = "normal",
}) => {
const { date, author } = meta;
const { created_at , author } = meta;
return (
<div
className={`nc-PostCardMeta inline-flex items-center fledx-wrap text-neutral-800 dark:text-neutral-200 ${
@ -24,8 +24,7 @@ const PostCardMeta: FC<PostCardMetaProps> = ({
} ${className}`}
data-nc-id="PostCardMeta"
>
<Link
href={author.href}
{/* <div
className="flex-shrink-0 relative flex items-center space-x-2"
>
{!hiddenAvatar && (
@ -34,20 +33,17 @@ const PostCardMeta: FC<PostCardMetaProps> = ({
sizeClass={
size === "normal" ? "h-7 w-7 text-sm" : "h-10 w-10 text-xl"
}
imgUrl={author.avatar}
userName={author.displayName}
imgUrl={author?.avatar}
userName={author?.fullname}
/>
)}
<span className="block text-neutral-6000 hover:text-black dark:text-neutral-300 dark:hover:text-white font-medium">
{author.displayName}
{author.fullname}
</span>
</Link>
</div> */}
<>
<span className="text-neutral-500 dark:text-neutral-400 mx-[6px] font-medium">
·
</span>
<span className="text-neutral-500 dark:text-neutral-400 font-normal line-clamp-1">
{date}
{created_at.split("T")[0]}
</span>
</>
</div>

2
src/data/jsons/__posts.json

@ -14,7 +14,7 @@
"like": { "count": 3366, "isLiked": true },
"authorId": 3,
"categoriesId": [3, 12],
"postType": "standard"
"postType": "video"
},
{
"index": 2,

39
src/data/types.ts

@ -36,19 +36,34 @@ export interface AuthorType {
starRating?: number;
}
export interface PostDataType {
id: string | number;
author: AuthorType;
date: string;
href: Route<string>;
categories: TaxonomyType[];
interface BlogAuthor {
id: number;
fullname: string;
avatar: string | null;
email: string | null;
phone_number: string | null;
available_password: string;
}
interface BlogTag {
id: number;
name: string;
slug: string;
}
export interface Blog {
id: number;
title: string;
featuredImage: StaticImageData | string;
desc?: string;
commentCount: number;
viewdCount: number;
readingTime: number;
postType?: "standard" | "video" | "gallery" | "audio";
slug: string;
author: BlogAuthor;
content: string;
summary: string;
tags: BlogTag[];
status: boolean;
created_at: string;
cover: string;
language: number;
has_voted: boolean;
}
export type TwMainColor =

Loading…
Cancel
Save