Skip to content

Commit

Permalink
adding preview
Browse files Browse the repository at this point in the history
  • Loading branch information
IslemMedjahdi committed Jan 5, 2023
1 parent 94f3dcf commit 518a183
Show file tree
Hide file tree
Showing 26 changed files with 504 additions and 35 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
NEXT_PUBLIC_BACKEND_URL=
NEXT_PUBLIC_BACKEND_HOSTNAME
NEXT_PUBLIC_GOOGLE_CLIENT_ID=
7 changes: 5 additions & 2 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
images: {
domains: [process.env.NEXT_PUBLIC_BACKEND_HOSTNAME],
},
};

module.exports = nextConfig
module.exports = nextConfig;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"dependencies": {
"@headlessui/react": "^1.7.7",
"@next/font": "13.1.0",
"@tailwindcss/typography": "^0.5.8",
"@types/node": "18.11.17",
"@types/react": "^18.0.26",
"@types/react-dom": "18.0.9",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import { useEffect, useState } from "react";
import DataTable, { TableColumn } from "react-data-table-component";
import { Autoplay } from "swiper";
import { Swiper, SwiperSlide } from "swiper/react";
import { ICONS } from "../../constants/icons";
import { IMAGES } from "../../constants/images";
import { ROUTES } from "../../constants/routes";
import AnnouncementService from "../../services/annoucement.service";
import { Announcement } from "../../typings/announcement";
import Loading from "../shared/Loading";
import { ICONS } from "../../../constants/icons";
import { IMAGES } from "../../../constants/images";
import { ROUTES } from "../../../constants/routes";
import AnnouncementService from "../../../services/annoucement.service";
import { Announcement } from "../../../typings/announcement";
import Loading from "../../shared/Loading";
// Import Swiper styles
import "swiper/css";
import { imageUrl } from "../../../utils/lib";

const announcementService = AnnouncementService.getInstance();

Expand All @@ -29,25 +30,20 @@ const columns: TableColumn<Announcement.AnnouncementPart>[] = [
name: "Photos",
cell: (row, index) => (
<>
{true || (row.photos && row.photos.length > 0) ? (
{row.photos && row.photos.length > 0 ? (
<>
<Swiper
modules={[Autoplay]}
loop={true}
autoplay={{
disableOnInteraction: false,
pauseOnMouseEnter: true,
delay: index % 2 ? 3000 : 4000,
}}
>
{[
IMAGES.Auth_background,
IMAGES.Auth_background_mobile,
IMAGES.NO_IMAGE,
].map((item, index) => (
<SwiperSlide key={index} className="!w-full">
{row.photos.map(({ id }, index) => (
<SwiperSlide key={index} className="!w-full overflow-hidden">
<Image
src={item}
src={imageUrl(id)}
alt="no-image"
className="aspect-video h-36 object-cover"
width={720}
Expand All @@ -61,7 +57,7 @@ const columns: TableColumn<Announcement.AnnouncementPart>[] = [
<Image
src={IMAGES.NO_IMAGE}
alt="no-image"
className="aspect-video h-36 object-cover"
className="pointer-events-none aspect-video h-36 object-cover"
width={720}
height={480}
/>
Expand All @@ -70,6 +66,16 @@ const columns: TableColumn<Announcement.AnnouncementPart>[] = [
),
grow: 3,
},
{
name: "Titre",
cell: (row) => (
<p className="text-sm font-medium">{row.titre || "indéfini"}</p>
),
selector: (row) => row.titre || "indéfini",
sortable: true,
reorder: true,
grow: 1.5,
},
{
name: "Catégorie",
cell: (row) => <p className="text-sm font-medium">{row.categorie}</p>,
Expand All @@ -81,9 +87,7 @@ const columns: TableColumn<Announcement.AnnouncementPart>[] = [
{
name: "Surface",
cell: (row) => (
<p className="text-sm font-medium">
{row.surface + " Km²" || "indéfini"}
</p>
<p className="text-sm font-medium">{row.surface + " m²" || "indéfini"}</p>
),
selector: (row) => row.surface || 0,
sortable: true,
Expand All @@ -99,11 +103,15 @@ const columns: TableColumn<Announcement.AnnouncementPart>[] = [
grow: 1,
},
{
name: "Type",
name: "Location",
cell: (row) => (
<p className="text-sm font-medium">{row.type || "indéfini"}</p>
<div className="flex flex-col text-sm font-medium">
<p>{row.localisation.commune}</p>
<p>{row.localisation.wilaya}</p>
</div>
),
selector: (row) => row.type || "indéfini",
selector: (row) =>
[row.localisation.commune, row.localisation.wilaya].join(" "),
sortable: true,
reorder: true,
grow: 1,
Expand Down Expand Up @@ -173,9 +181,9 @@ const PostedAnnouncementIndex: React.FC = () => {

return (
<div className="flex justify-center">
<div className="container max-w-screen-lg px-4">
<div className="container px-4">
<div className="flex justify-center py-10">
<h1 className="relative z-10 text-center font-serif text-3xl font-semibold after:absolute after:top-full after:left-0 after:h-2 after:w-full after:origin-left after:skew-y-1 after:animate-reveal after:bg-blue-primary">
<h1 className="relative z-10 text-center font-serif text-3xl font-semibold text-gray-900 after:absolute after:top-full after:left-0 after:h-2 after:w-full after:origin-left after:skew-y-1 after:animate-reveal after:bg-blue-primary">
Vos announces déposées
</h1>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { NextSeo } from "next-seo";
import { useRouter } from "next/router";
import React, { useEffect, useState } from "react";
import { ROUTES } from "../../../constants/routes";
import AnnouncementService from "../../../services/annoucement.service";
import { Announcement } from "../../../typings/announcement";
import Loading from "../../shared/Loading";
import BriefInfo from "./BriefInfo";
import ContactForm from "./ContactForm";
import Description from "./Description";
import Gallery from "./Gallery";
import PosterInfo from "./PosterInfo";
import PriceInfo from "./PriceInfo";

const announcementService = AnnouncementService.getInstance();

const AnnouncementPreviewIndex: React.FC = () => {
const router = useRouter();

const [annoucement, setAnnouncement] =
useState<Announcement.Announcement | null>(null);
const [loading, setLoading] = useState(true);

const getAnnouncement = async (id: number) => {
setLoading(true);
try {
const response = await announcementService.getAnnouncementById(id);
setAnnouncement(response.data);
} catch (e) {
await router.push(ROUTES.ERROR.path);
} finally {
setLoading(false);
}
};

useEffect(() => {
if (router.query.id) {
if (typeof router.query.id === "string") {
getAnnouncement(parseInt(router.query.id));
} else {
router.push(ROUTES.ERROR.path);
}
}
}, [router]);

return (
<>
<NextSeo title={annoucement?.titre || ""} />
{loading || !annoucement ? (
<div className="flex h-96 items-center justify-center">
<Loading />
</div>
) : (
<div className="flex justify-center">
<div className="container py-10 px-4">
<div>
<h1 className="relative z-10 font-serif text-3xl font-semibold text-gray-900">
{annoucement.titre}
</h1>
<div className="mt-10 grid grid-cols-1 gap-4 lg:grid-cols-6">
<div className="lg:col-span-4">
<div className="flex w-full flex-col rounded-sm bg-white shadow">
<Gallery photos={annoucement.photos} />
<hr />
<div className="flex w-full justify-center px-4 py-6">
<div className="flex w-full max-w-screen-sm flex-col gap-y-6">
<BriefInfo
category={annoucement.categorie}
surface={annoucement.surface}
wilaya={annoucement.localisation.wilaya}
commun={annoucement.localisation.commune}
adress={annoucement.adresse}
/>
<PriceInfo price={annoucement.prix} />
<Description text={annoucement.description || ""} />
</div>
</div>
</div>
</div>
<div className="lg:col-span-2">
<div className="w-full gap-y-4 rounded-sm bg-blue-light shadow lg:col-span-2">
<ContactForm />
<hr />
<PosterInfo
email={annoucement.auteur.email}
firstName={annoucement.auteur.nom}
lastName={annoucement.auteur.prenom}
phone={annoucement.auteur.tel}
/>
</div>
</div>
</div>
</div>
</div>
</div>
)}
</>
);
};

export default AnnouncementPreviewIndex;
47 changes: 47 additions & 0 deletions src/components/announcements/preview-annoucement/BriefInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import { ICONS } from "../../../constants/icons";
import { Announcement } from "../../../typings/announcement";

type Props = {
category: Announcement.Category;
surface?: number;
wilaya: string;
commun: string;
adress: string;
};

const BriefInfo: React.FC<Props> = ({
category,
surface,
wilaya,
commun,
adress,
}) => {
return (
<div className="flex flex-col gap-y-6">
<div className="flex flex-wrap items-center justify-center gap-x-16 gap-y-4 text-gray-800">
<div className="flex items-center gap-4">
<ICONS.Category className="text-2xl text-blue-primary" />
<p className="font-serif font-bold">{category}</p>
</div>
<div className="flex items-center gap-4">
<ICONS.Surface className="text-2xl text-blue-primary" />
<p className="font-serif font-bold">{surface + " m²" || "Inconné"}</p>
</div>
<div className="flex items-center gap-4">
<ICONS.Map className="text-2xl text-blue-primary" />
<p className="font-serif font-bold">
{commun}, {wilaya}
</p>
</div>
</div>
<div>
<p className="font-serif">
<span className="text-lg font-bold">Adresse:</span> {adress}
</p>
</div>
</div>
);
};

export default BriefInfo;
38 changes: 38 additions & 0 deletions src/components/announcements/preview-annoucement/ContactForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useState } from "react";

const ContactForm = () => {
const [message, setMessage] = useState<string>("");

const sendMessage = async () => {};

return (
<div className="flex flex-col gap-y-4 p-4">
<p className="relative w-fit font-serif text-lg font-bold after:absolute after:bottom-0 after:left-0 after:h-1 after:w-full after:origin-left after:skew-y-[0.5deg] after:bg-blue-primary after:transition after:duration-300 hover:after:scale-x-100">
Contactez nous
</p>
<div className="flex flex-col gap-y-2">
<label className="text-sm font-medium text-gray-800" htmlFor="message">
Message
</label>
<textarea
rows={5}
name="message"
id="message"
className="w-full rounded-sm border p-4 text-sm text-gray-900 shadow-sm outline-none"
placeholder="message"
/>
<p className="text-xs">
Vos informations seront transmises au propriétaire de l'annonce.
</p>
<button
onClick={sendMessage}
className="rounded-sm bg-blue-primary px-4 py-2 text-sm text-white transition duration-200 hover:bg-blue-hover"
>
Envoyer
</button>
</div>
</div>
);
};

export default ContactForm;
24 changes: 24 additions & 0 deletions src/components/announcements/preview-annoucement/Description.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react";

type Props = {
text: string;
};

const Description: React.FC<Props> = ({ text }) => {
return (
<div>
<h1 className="font-serif text-lg font-bold text-gray-900">
Description:
</h1>
<div className="prose prose-sm prose-a:text-blue-primary">
<div
dangerouslySetInnerHTML={{
__html: text,
}}
/>
</div>
</div>
);
};

export default Description;
Loading

0 comments on commit 518a183

Please sign in to comment.