Commit e5c83327 by Ravindra Kanojiya

blog api updated

1 parent 87175bba
......@@ -2,12 +2,14 @@ import React from 'react'
import PageBanner from './PageBanner'
import BlogsDetailInner from './BlogsDetailInner'
import MostReadBlogs from './MostReadBlogs'
import { useDispatch, useSelector } from "react-redux";
const BlogDetails = () => {
const { blog } = useSelector(state => state.blog);
console.log("blog >>>>>", blog)
return (
<>
<PageBanner />
<BlogsDetailInner />
<PageBanner blog={blog} />
<BlogsDetailInner blog={blog}/>
<MostReadBlogs />
</>
)
......
import Image from 'next/image'
import React from 'react'
import Image from "next/image";
import React from "react";
import { cleanImage } from "../../services/imageHandling";
const BlogsDetailInner = () => {
const BlogsDetailInner = ({ blog }) => {
let mainBlog;
if (blog && blog.length > 0) {
mainBlog = blog[0];
}
console.log("mainBlog", blog)
return (
<section className='blog-detail-inner-session'>
<div className='container'>
<div className='row align-items-center mb-3'>
<div className='col-md-6'>
<div className='profile'>
<span className='image-container'>
<Image layout='fill' alt='' className='image img-fluid' src="/images/blog-pic.png" />
</span>
<div className='name'>By John Smith</div>
</div>
</div>
<div className='col-md-6'>
<div className='date'>
<span className='image-container'>
<Image layout='fill' alt='' className='image img-fluid' src="/images/icons/calendar.svg" />
</span>
<div className=''>27th Jan 2024</div>
</div>
</div>
<section className="blog-detail-inner-session">
<div className="container">
<div className="row align-items-center mb-3">
<div className="col-md-6">
<div className="profile">
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src={cleanImage(mainBlog?.attributes?.profilePic?.data?.attributes)} />
</span>
<div className="name">{mainBlog?.attributes?.name}</div>
</div>
<div className='row'>
<div className='col-12'>
<ul className='flag-list'>
<li>
<a href="">Adventure</a>
</li>
<li>
<a href="">Fun</a>
</li>
<li>
<a href="">Lorem Ipsum</a>
</li>
</ul>
</div>
</div>
<div className="col-md-6">
<div className="date">
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/icons/calendar.svg" />
</span>
<div className="">{mainBlog?.attributes?.date}</div>
</div>
<div className='row'>
<div className='col-12'>
<h2>13 MOST Unique Places to Stay in Washington State</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum </p>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum </p>
</div>
</div>
<div className="row">
<div className="col-12">
<ul className="flag-list">
<li>
<a href="">{mainBlog?.attributes?.categories}</a>
</li>
<li>
<a href="">Fun</a>
</li>
<li>
<a href="">Lorem Ipsum</a>
</li>
</ul>
</div>
</div>
<div className="row">
<div className="col-12">
<h2>{mainBlog?.attributes?.title}</h2>
<div dangerouslySetInnerHTML={{__html: mainBlog?.attributes?.description}}></div>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur</p>
</div>
</div>
</div>
</div>
</div>
</section>
)
}
);
};
export default BlogsDetailInner
export default BlogsDetailInner;
......@@ -10,7 +10,7 @@ import { Navigation, Autoplay } from "swiper/modules";
import "swiper/css";
import "swiper/css/pagination";
import "swiper/css/navigation";
import { BlogData } from "../blogs/BlogsItem.js";
import { BlogData } from "../blog/BlogItem.js";
import Image from "next/image.js";
const MostReadBlogs = () => {
return (
......
......@@ -2,13 +2,19 @@ import Image from "next/image";
import React from "react";
import { fadeIn, zoomIn, slideFromLeft, slideFromRight } from "../animationvariants.js";
import { motion } from "framer-motion";
const PageBanner = () => {
import { cleanImage } from "../../services/imageHandling.js";
const PageBanner = ({blog}) => {
let mainBlog;
if (blog && blog.length > 0) {
mainBlog = blog[0];
}
console.log("123", mainBlog)
return (
<>
<div className="page-title-area">
<div className="banner-bg">
<span className="image-container hide-on-mobile">
<Image layout="fill" className="image img-fluid" alt="" src="/images/blogs/01.png" />
<Image layout="fill" className="image img-fluid" alt="" src={cleanImage(mainBlog?.attributes?.image?.data?.attributes)} />
</span>
<span className="image-container hide-on-desktop">
<Image layout="fill" className="image img-fluid" alt="" src="/images/blogs/01.png" />
......
import React from "react";
import { fadeIn, zoomIn, slideFromLeft, slideFromRight } from "../animationvariants.js";
import { motion } from "framer-motion";
import BlogsItem from "./BlogsItem.js";
import BlogsItem from "./BlogItem.js";
import PageBanner from "./PageBanner.js";
const Blogs = () => {
import { useDispatch, useSelector } from "react-redux";
const Blog = () => {
const { blogs } = useSelector(state => state.blogs);
console.log("blogs", blogs)
return (
<>
<PageBanner />
<BlogsItem />
<BlogsItem blogs={blogs} />
</>
);
};
export default Blogs;
export default Blog;
......@@ -3,6 +3,7 @@ import { fadeIn, zoomIn, slideFromLeft, slideFromRight } from "../animationvaria
import { motion } from "framer-motion";
import Image from "next/image.js";
import { Accordion, Button, Form } from "react-bootstrap";
import { cleanImage } from "../../services/imageHandling.js";
export const BlogData = [
{
image: "/images/blogs/01.png",
......@@ -48,7 +49,7 @@ export const BlogData = [
}
];
const BlogsItem = () => {
const BlogsItem = ({blogs}) => {
const [showContent, setShowContent] = useState(false);
const [isGridViewOpen, setIsGridViewOpen] = useState(false);
const [isOpen, setIsOpen] = useState(false);
......@@ -298,28 +299,28 @@ const BlogsItem = () => {
<div className="row">
<div className="col-12">
<div className="row">
{BlogData &&
BlogData.map(data => {
{blogs &&
blogs.map(data => {
return (
<div className="col-md-4">
<div className="blog-item">
<div className="img-wrapper">
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src={data.image} />
<Image layout="fill" alt="" className="image img-fluid" src={cleanImage(data?.attributes?.image?.data?.attributes)} />
</span>
<div className="top-rated">{data.flag}</div>
<div className="top-rated">{data?.attributes?.categories}</div>
</div>
<div className="info">
<div className="read-row">
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/icons/clock.svg" />
</span>
<div className="">{data.read}</div>
<div className="">{data?.attributes?.read} Read</div>
</div>
<div className="title">{data.title}</div>
<div className="discription">{data.discription}</div>
<div className="title">{data?.attributes?.title}</div>
<div className="discription" dangerouslySetInnerHTML={{ __html: data?.attributes?.description }}></div>
<div className="read-more">
<Button href="/blog-details" variant="primary">
<Button href={`/blog/${data.attributes.slug}`} variant="primary">
Read More
</Button>
</div>
......
......@@ -11,65 +11,10 @@ import { motion } from "framer-motion";
import "swiper/css";
import "swiper/css/pagination";
import "swiper/css/navigation";
const BrowseExperiences = () => {
import { cleanImage } from "../../services/imageHandling.js";
const BrowseExperiences = ({allActivitiesData}) => {
const ListingData = [
{
image: "/images/Browse-Experiences/01.png",
topRated: "Top Rated",
title: "City Climb",
discription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
price: "200",
offPrice: "40%",
days: "For 1 Night",
taxes: "Includes taxes & Fees",
id: 1,
},
{
image: "/images/Browse-Experiences/02.png",
topRated: "Top Rated",
title: "City Climb",
discription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
price: "200",
offPrice: "40%",
days: "For 1 Night",
taxes: "Includes taxes & Fees",
id: 2,
},
{
image: "/images/Browse-Experiences/03.png",
topRated: "Top Rated",
title: "City Climb",
discription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
price: "200",
offPrice: "40%",
days: "For 1 Night",
taxes: "Includes taxes & Fees",
id: 3,
},
{
image: "/images/Browse-Experiences/04.png",
topRated: "Top Rated",
title: "City Climb",
discription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
price: "200",
offPrice: "40%",
days: "For 1 Night",
taxes: "Includes taxes & Fees",
id: 4,
},
{
image: "/images/Browse-Experiences/01.png",
topRated: "Top Rated",
title: "City Climb",
discription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
price: "200",
offPrice: "40%",
days: "For 1 Night",
taxes: "Includes taxes & Fees",
id: 5,
}
];
return (
<>
......@@ -118,8 +63,8 @@ const BrowseExperiences = () => {
modules={[Navigation, Autoplay]}
className="mySwiper01 mySwiper02"
>
{ListingData &&
ListingData.map(data => {
{allActivitiesData.data &&
allActivitiesData.data.map(data => {
return (
<SwiperSlide key={data?.id}>
<motion.div
......@@ -131,16 +76,16 @@ const BrowseExperiences = () => {
<div className="browse-experiences-item">
<div className="img-wrapper">
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src={data.image} />
<Image layout="fill" alt="" className="image img-fluid" src={cleanImage(data.attributes?.image?.data?.attributes)} />
</span>
<div className="top-rated">{data.topRated}</div>
<div className="top-rated">Top Rated</div>
</div>
<div className="info">
<div className="top-name">
<div className="title">{data.title}</div>
<div className="title">{data?.attributes?.name}</div>
<div className="rating-wishlist">
<div className="rating">
8.8
{data?.attributes?.rating}
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/icons/star.svg" />
</span>
......@@ -156,11 +101,11 @@ const BrowseExperiences = () => {
{data.discription} <a href="">Read More</a>
</div>
<div className="price">
${data.price} <span className="off">{data.offPrice} OFF</span>
${data?.attributes?.pricePerPerson} <span className="off">{data?.attributes?.off}% OFF</span>
</div>
<div className="detail">
<div className="">{data.days}</div>
<div className="">{data.taxes}</div>
<div className="">For 1 Night</div>
<div className="">Includes taxes & Fees</div>
</div>
<div className="explore-now">
<Button href="/listing" variant="primary">Explore Now</Button>
......
......@@ -11,8 +11,10 @@ import { useDispatch, useSelector } from "react-redux";
const Home = () => {
const { categories } = useSelector(state => state.categories);
const { testimonial } = useSelector(sate => sate.testimonial);
const { allActivitiesData } = useSelector(sate => sate.allActivitiesData);
console.log("categories", categories )
console.log("testimonial", testimonial )
console.log("allActivitiesData", allActivitiesData )
const dispatch = useDispatch();
useEffect(() => {
// dispatch(getHomePage())
......@@ -23,7 +25,7 @@ const Home = () => {
<Banner />
<SearchBar />
<LetDiscover categories={categories} />
<BrowseExperiences />
<BrowseExperiences allActivitiesData={allActivitiesData} />
<GiftAnExperience />
<Testimonial testimonial={testimonial} />
<SignUpToExperienceOurPlatform />
......
import AboutUs from "../components/about-us/AboutUs";
import BlogDetails from "../components/blog-details/BlogDetails";
import Blogs from "../components/blogs/Blogs";
import Home from "../components/home/Home";
import Layout from "../components/layout/Layout";
import { loadUser } from "../redux/actions/userActions";
import { wrapper } from "../redux/store";
export default function BlogDetailsPage() {
return (
<Layout>
<BlogDetails />
</Layout>
);
}
/** For server side rendering */
export const getServerSideProps = wrapper.getServerSideProps(store => async ({ req, query }) => {
// Get the menu data.
// get the locations data.
// await store.dispatch(loadUser())
return {
props: {},
};
});
import AboutUs from "../components/about-us/AboutUs";
import Blogs from "../components/blogs/Blogs";
import Blog from "../components/blog/Blog";
import Home from "../components/home/Home";
import Layout from "../components/layout/Layout";
import { getBlogData, getBlogsData } from "../redux/actions/blogAction";
import { loadUser } from "../redux/actions/userActions";
import { wrapper } from "../redux/store";
......@@ -9,20 +10,28 @@ export default function BlogsPage() {
return (
<Layout>
<Blogs />
<Blog />
</Layout>
);
}
/** For server side rendering */
export const getServerSideProps = wrapper.getServerSideProps(store => async ({ req, query }) => {
// Get the menu data.
// get the locations data.
// await store.dispatch(loadUser())
try {
await store.dispatch(getBlogsData())
return {
props: {},
// Next.js will attempt to re-generate the page:
// - Any requests to the page after the initial request and before 10 seconds are also cached and instantaneous.
// - After the 10-second window, the next request will still show the cached (stale) page
// - Next.js triggers a regeneration of the page in the background.
// - Once the page generates successfully, Next.js will invalidate the cache and show the updated page. If the background regeneration fails, the old page would still be unaltered.
// In seconds
// revalidate: Number(process.env.NEXT_PUBLIC_ISR_REVALIDATE_AFTER)
};
} catch (error) {
console.log("index.js", error);
}
});
import BlogDetails from "../../components/blog-details/BlogDetails";
import Layout from "../../components/layout/Layout";
import { getBlogData } from "../../redux/actions/blogAction";
import { wrapper } from "../../redux/store";
export default function BlogDetailsPage() {
return (
<Layout>
<BlogDetails />
</Layout>
);
}
/** For server side rendering */
export const getServerSideProps = wrapper.getServerSideProps(store => async ({ req, query }) => {
try {
console.log("query", query);
await store.dispatch(getBlogData(query.slug))
return {
props: {},
// Next.js will attempt to re-generate the page:
// - Any requests to the page after the initial request and before 10 seconds are also cached and instantaneous.
// - After the 10-second window, the next request will still show the cached (stale) page
// - Next.js triggers a regeneration of the page in the background.
// - Once the page generates successfully, Next.js will invalidate the cache and show the updated page. If the background regeneration fails, the old page would still be unaltered.
// In seconds
// revalidate: Number(process.env.NEXT_PUBLIC_ISR_REVALIDATE_AFTER)
};
} catch (error) {
console.log("index.js", error);
}
});
import Home from "../components/home/Home";
import Layout from "../components/layout/Layout";
import { getActivitiesByVendor } from "../redux/actions/activityAction";
import { getAllCategories } from "../redux/actions/categoriesAction";
import { getTestimonial } from "../redux/actions/testimonialAction";
import { loadUser } from "../redux/actions/userActions";
......@@ -27,6 +28,7 @@ export const getServerSideProps = wrapper.getServerSideProps(store => async ({ r
try {
await store.dispatch(getAllCategories())
await store.dispatch(getTestimonial())
await store.dispatch(getActivitiesByVendor())
return {
props: {},
......
......@@ -96,7 +96,7 @@ export const getActivitiesByVendor = () => async dispatch => {
const query = {
filters: {},
populate: ["masterMonths", "subCategory", "subCategory.category", "timeSlots", "masterPincode", "vendor"]
populate: ["masterMonths", "subCategory", "subCategory.category", "timeSlots", "masterPincode", "vendor", "image"]
};
const queryString = qs.stringify(query, {
......
import axios from "axios";
import qs from "qs";
import { FETCH_BLOGS_FAIL, FETCH_BLOGS_REQUEST, FETCH_BLOGS_SUCCESS, FETCH_BLOG_FAIL, FETCH_BLOG_REQUEST, FETCH_BLOG_SUCCESS } from "../constants/blogConstants";
export const getBlogsData =
() =>
async dispatch => {
try {
console.log("HI >>>>>")
dispatch({
type: FETCH_BLOGS_REQUEST
});
const config = {
headers: {
"Content-Type": "application/json"
}
};
const query = {
// pagination: {
// pageSize: 12,
// page: currentPage
// },
filters: {
category: {
name: {}
}
},
populate: ["image"],
sort: ["updatedAt:desc"]
// pagination: {}
// pageSize: -1,
};
const queryString = qs.stringify(query, {
encodeValuesOnly: true
});
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/blogs/?${queryString}`);
dispatch({
// type: published ? PUBLISHED_ROOMS_SUCCESS : ADMIN_ROOMS_SUCCESS,
type: FETCH_BLOGS_SUCCESS,
payload: response.data
});
} catch (error) {
dispatch({
// type: published ? PUBLISHED_ROOMS_FAIL : ADMIN_ROOMS_FAIL,
type: FETCH_BLOGS_FAIL,
payload: error.response.data
});
}
};
export const getBlogData = slug => async dispatch => {
try {
dispatch({
type: FETCH_BLOG_REQUEST
});
const query = {
filters: {},
populate: ["image","profilePic"],
pagination: {}
};
// if (country) {
// query.filters["country"] = { $eq: country };
// }
query.filters["slug"] = { $eq: slug };
// if (category) {
// }
const queryString = qs.stringify(query, {
encodeValuesOnly: true
});
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/blogs/?${queryString}`);
dispatch({
// type: published ? PUBLISHED_ROOMS_SUCCESS : ADMIN_ROOMS_SUCCESS,
type: FETCH_BLOG_SUCCESS,
payload: response.data
});
} catch (error) {
dispatch({
// type: published ? PUBLISHED_ROOMS_FAIL : ADMIN_ROOMS_FAIL,
type: FETCH_BLOG_FAIL,
payload: error.response.data
});
}
};
export const FETCH_BLOGS_REQUEST = "FETCH_BLOGS_REQUEST";
export const FETCH_BLOGS_SUCCESS = "FETCH_BLOGS_SUCCESS";
export const FETCH_BLOGS_FAIL = "FETCH_BLOGS_FAIL";
export const FETCH_BLOG_REQUEST = "FETCH_BLOG_REQUEST";
export const FETCH_BLOG_SUCCESS = "FETCH_BLOG_SUCCESS";
export const FETCH_BLOG_FAIL = "FETCH_BLOG_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
import { FETCH_BLOGS_FAIL, FETCH_BLOGS_REQUEST, FETCH_BLOGS_SUCCESS, FETCH_BLOG_FAIL, FETCH_BLOG_REQUEST, FETCH_BLOG_SUCCESS, CLEAR_ERRORS } from "../constants/blogConstants";
export const blogsReducer = (state = { blogs: {} }, action) => {
switch (action.type) {
case FETCH_BLOGS_REQUEST:
return {
loading: true
};
case FETCH_BLOGS_SUCCESS:
return {
blogs: action.payload.data,
// totalCount: action.payload.meta.pagination.total,
// resultsPerPage: action.payload.meta.pagination.pageSize
};
case FETCH_BLOGS_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
export const blogReducer = (state = { blog: {} }, action) => {
switch (action.type) {
case FETCH_BLOG_REQUEST:
return {
loading: true
};
case FETCH_BLOG_SUCCESS:
return {
blog: action.payload.data
};
case FETCH_BLOG_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
......@@ -8,6 +8,7 @@ import { getVendorDetailsReducer, loggedInVendorReducer, updateVendorReducer } f
import { createActivityReducer, getActivitiesReducer } from "./activitiesReducer";
import { getAllCategoriesReducer, getAllSubCategoriesReducer } from "./categoryReducer";
import { getAllTestimonialReducer } from "./testimonialReducer";
import { blogReducer, blogsReducer } from "./blogReducer";
const reducers = combineReducers({
townships: townshipsReducer,
......@@ -30,6 +31,8 @@ const reducers = combineReducers({
subCategories: getAllSubCategoriesReducer,
testimonial: getAllTestimonialReducer,
allActivitiesData: getActivitiesReducer,
blogs: blogsReducer,
blog: blogReducer
});
export default reducers;
......@@ -1909,7 +1909,8 @@ span.form-error,
}
.info .top-name .title {
font-size: 20px;
font-size: 17px;
line-height: 20px;
}
.info .rating-wishlist .rating {
......@@ -2832,7 +2833,16 @@ footer hr {
margin-top: -20px;
margin-bottom: 5rem;
}
.page-title-area .banner-bg .image-container{
height: 100%;
display: block;
}
.page-title-area .banner-bg .image-container>span{
height: 100% !important;
}
.page-title-area .banner-bg .image{
object-fit: cover;
}
.page-title-one {
background: url(/images/banner/about-us.png);
}
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!