QandA Made And Completed, Product Page Layout Done ( No Footer )

temp
Pedram Keshavarzi 3 years ago
parent 313c9b9ae6
commit 48ddb1fdc7
  1. 19
      src/components/Avatar/index.js
  2. 113
      src/components/Comments/index.js
  3. 7
      src/components/Comments/negative.svg
  4. 9
      src/components/Comments/positive.svg
  5. 11
      src/components/Comments/user.svg
  6. 7
      src/components/Counter/black-dislike-icon.svg
  7. 7
      src/components/Counter/black-like-icon.svg
  8. 40
      src/components/Counter/index.js
  9. 158
      src/components/QandA/index.js
  10. 22
      src/utils/comments.js
  11. 3
      src/views/Product/Desktop/ProductOverAll/index.js
  12. 20
      src/views/Product/Desktop/index.js

@ -0,0 +1,19 @@
import React from "react";
import userImage from "../../assets/images/user.png";
function Avatar({ source, size, rounded, status }) {
return (
<div className={`${rounded} overflow-hidden relative`}>
<img
src={source ? source : userImage}
alt="avatar"
style={{ width: size, height: size, objectFit: "cover" }}
/>
{status && (
<span className="w-1.5 h-1.5 rounded-full bg-green-500"></span>
)}
</div>
);
}
export default Avatar;

@ -0,0 +1,113 @@
import React from "react";
import { connect } from "react-redux";
// import { connectToParent } from "../../utils/comments";
import userImage from "./user.svg";
import positiveIcon from "./positive.svg";
import negativeIcon from "./negative.svg";
import Avatar from "../Avatar"
import moment from "jalali-moment";
import Button from '../Button';
import StarRating from "../StarRating";
export const Comments = ({ comments }) => {
// connectToParent(comments);
const Comment = ({ comment }) => {
return (
<div className="flex flex-col w-full">
<header className="w-full flex flex-row justify-between py-1">
<div className="flex flex-row items-end">
<Avatar source={comment.userImage} size={60} rounded={true} />
<div className="flex flex-col">
<strong className="text-lg mr-2">{comment.username}</strong>
<div
className="flex flex-row divide-x divide-gray-300 mt-4 divided items-center"
style={{ direction: "ltr" }}
>
<span className="px-2 text-xs text-gray-500">
{comment.product?.color}
</span>
<span className="px-2 text-xs text-gray-500">
{comment.product?.name}
</span>
</div>
</div>
</div>
<div
className="flex flex-row divide-x divide-gray-300 divided items-center"
style={{ direction: "ltr" }}
>
<span className="px-2 text-sm text-blue-400">
{moment(comment.data).locale("fa").format("YYYY/MM/DD")}
</span>
<span className="px-2 text-sm text-blue-400">
{comment.date.getHours()}&nbsp;:&nbsp;{comment.date.getMinutes()}
</span>
</div>
</header>
<div className="flex flex-row py-4">
<div style={{ width: 60 }} className="min-h-full"></div>
<div className="flex flex-1 flex-col px-3">
<header className="w-full flex flex-row justify-between items-center">
<div className="flex flex-row items-center"><StarRating /></div>
<div className="flex flex-row items-center">
{comment.status === true && (
<>
<img src={positiveIcon} alt="" className="w-6 ml-2" />
<span className="text-sm text-black">
برای خرید توصیه میکنم
</span>
</>
)}
{comment.status === false && (
<>
<img src={negativeIcon} alt="" className="w-6 ml-2" />
<span className="text-sm text-black">
برای خرید توصیه نمیکنم
</span>
</>
)}
</div>
</header>
<p className="text-gray-500 mt-2">{comment.text}</p>
<div className="self-end mt-4">
{/* <Button title='اطلاعات بیشتر' backgroundColor='bg-gray-200' width={}/> */}
</div>
</div>
</div>
</div>
);
};
return (
<div className="w-full flex flex-col">
{comments.map((comment, index) => (
<Comment comment={comment} key={index} />
))}
</div>
);
};
const mapStateToProps = (state) => ({});
const mapDispatchToProps = {};
export default connect(mapStateToProps, mapDispatchToProps)(Comments);
Comments.defaultProps = {
comments: [
{
id: 0,
pid: null,
username: "آرش سامانی",
date: new Date(),
text: "خالد حسینی تو رمان باد بادک باز مینویسه : ﻣﺮﺩ ﺁﻫﺴﺘﻪ ﺩﺭ ﮔﻮﺵ ﻓﺮﺯﻧﺪ ﺗﺎﺯﻩ ﺑﻪ ﺑﻠﻮﻍ ﺭﺳﯿﺪﻩ ﺍﺵ ﺑﺮﺍﯼ ﭘﻨﺪ ﭼﻨﯿﻦ ﻧﺠﻮﺍ ﮐﺮﺩ : ” ﭘﺴﺮﻡ ﺩﺭ ﺯﻧﺪﮔﯽ ﻫﺮﮔﺰ ﺩﺯﺩﯼ ﻧﮑﻦ ” ﭘﺴﺮ ﻣﺘﻌﺠﺐ ﻭ ﻣﺒﻬﻮﺕ ﺑﻪ ﭘﺪﺭ ﻧﮕﺎﻩ ﮐﺮﺩ ﺑﺪﯾﻦ ﻣﻌﻨﺎ ﮐﻪ ﺍﻭ ﻫﺮﮔﺰ ﺩﺳﺖ ﮐﺞ ﻧﺪﺍﺷﺘﻪ ﭘﺪﺭ ﺑﻪ ﻧﮕﺎﻩ ﻣﺘﻌﺠﺐ ﻓﺮﺯﻧﺪ ﻟﺒﺨﻨﺪﯼ ﺯﺩ ﻭ ﺍﺩﺍﻣﻪ ",
userImage: userImage,
rate: 4,
product: {
name: "مک بوک پرو 16 گیگ",
color: "خاکستری",
},
status: true,
},
],
};

@ -0,0 +1,7 @@
<svg id="vuesax_linear_clipboard-close" data-name="vuesax/linear/clipboard-close" xmlns="http://www.w3.org/2000/svg" width="55.763" height="55.763" viewBox="0 0 55.763 55.763">
<g id="clipboard-close" transform="translate(0 0)">
<path id="Vector" d="M9.2,9.2,0,0" transform="translate(23.327 27.881)" fill="none" stroke="#ff0902" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path id="Vector-2" data-name="Vector" d="M9.2,0,0,9.2" transform="translate(23.235 27.974)" fill="none" stroke="#ff0902" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path id="Vector-3" data-name="Vector" d="M0,0H55.763V55.763H0Z" transform="translate(0)" fill="none" opacity="0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 728 B

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="42.324" height="42.324" viewBox="0 0 42.324 42.324">
<g id="vuesax_linear_tick-circle" data-name="vuesax/linear/tick-circle" transform="translate(-748 -188)">
<g id="tick-circle" transform="translate(748 188)">
<path id="Vector" d="M17.635,35.27A17.635,17.635,0,1,0,0,17.635,17.687,17.687,0,0,0,17.635,35.27Z" transform="translate(3.527 3.527)" fill="none" stroke="#20d513" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path id="Vector-2" data-name="Vector" d="M0,4.991,4.991,9.981,14.99,0" transform="translate(13.667 16.171)" fill="none" stroke="#20d513" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path id="Vector-3" data-name="Vector" d="M0,0H42.324V42.324H0Z" fill="none" opacity="0"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 829 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 119 KiB

@ -0,0 +1,7 @@
<svg id="vuesax_linear_dislike" data-name="vuesax/linear/dislike" xmlns="http://www.w3.org/2000/svg" width="49.199" height="49.199" viewBox="0 0 49.199 49.199">
<g id="dislike" transform="translate(0 0)">
<path id="Vector" d="M28.984,6.15,22.629,1.23A6.308,6.308,0,0,0,18.734,0h-7.79A6.157,6.157,0,0,0,5.2,4.3L.285,19.27C-.74,22.14,1.1,24.6,4.18,24.6h8.2a2.068,2.068,0,0,1,2.05,2.46L13.4,33.619a4.044,4.044,0,0,0,2.665,4.51,4.093,4.093,0,0,0,4.51-1.435l8.4-12.5" transform="translate(4.881 5.432)" fill="none" stroke="#818181" stroke-width="1.5"/>
<path id="Vector-2" data-name="Vector" d="M10.25,3.895v20.09c0,2.87-1.23,3.895-4.1,3.895H4.1c-2.87,0-4.1-1.025-4.1-3.895V3.895C0,1.025,1.23,0,4.1,0H6.15C9.02,0,10.25,1.025,10.25,3.895Z" transform="translate(34.07 7.687)" fill="none" stroke="#818181" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
<path id="Vector-3" data-name="Vector" d="M0,0H49.2V49.2H0Z" fill="none" opacity="0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 981 B

@ -0,0 +1,7 @@
<svg id="vuesax_linear_like" data-name="vuesax/linear/like" xmlns="http://www.w3.org/2000/svg" width="49.199" height="49.199" viewBox="0 0 49.199 49.199">
<g id="like" transform="translate(0 0)">
<path id="Vector" d="M0,32.189l6.355,4.92a6.308,6.308,0,0,0,3.895,1.23h7.79a6.157,6.157,0,0,0,5.74-4.3L28.7,19.069c1.025-2.87-.82-5.33-3.895-5.33H16.6a2.068,2.068,0,0,1-2.05-2.46l1.025-6.56A4.044,4.044,0,0,0,12.915.209,4.093,4.093,0,0,0,8.4,1.644L0,14.149" transform="translate(15.334 5.428)" fill="#fff" stroke="#818181" stroke-width="1.5"/>
<path id="Vector-2" data-name="Vector" d="M0,23.985V3.895C0,1.025,1.23,0,4.1,0H6.15c2.87,0,4.1,1.025,4.1,3.895v20.09c0,2.87-1.23,3.895-4.1,3.895H4.1C1.23,27.88,0,26.855,0,23.985Z" transform="translate(4.879 13.632)" fill="#fff" stroke="#818181" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
<path id="Vector-3" data-name="Vector" d="M0,0H49.2V49.2H0Z" fill="#fff" opacity="0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 967 B

@ -0,0 +1,40 @@
import React, { useState } from "react";
import blackDisLikeIcon from "./black-dislike-icon.svg";
import blackLikeIcon from "./black-like-icon.svg";
const Counter = ({ incrementIcon, decrementIcon, flex, value }) => {
const [count, setCount] = useState(value);
return (
<div className={`flex ${flex} items-center`}>
<img
src={incrementIcon}
alt=""
className="w-8 cursor-pointer pointer transition delay-150 duration-300 ease-in-out transform hover:-translate-y-2"
onClick={() => setCount(count + 1)}
/>
<span
className={`text-sm sm:text-base md:text-2xl font-bold text-color ${flex === 'flex-col' ? 'my-2' : 'mx-2'}`}
style={count > 0 ? { color: "green" } : { color: "red" }}
>
{count}
</span>
<img
src={decrementIcon}
alt=""
className="w-8 cursor-pointer transition delay-150 duration-300 ease-in-out transform hover:translate-y-2"
onClick={() => setCount(count - 1)}
/>
</div>
);
};
export default Counter;
Counter.defaultProps = {
incrementIcon: blackLikeIcon,
decrementIcon: blackDisLikeIcon,
flex: "flex-col",
value: 0
};

@ -0,0 +1,158 @@
import React, { useState } from 'react';
import moment from "jalali-moment";
import StarRating from "../StarRating";
import Counter from '../Counter';
import Button from '../Button';
const QandA = ({comments}) =>{
const Comment = ({ comment }) => {
const [open, Setopen] = useState(true);
const [viewmore, setViewMore] = useState("مشاهده باسخ های بیشتر");
const [numberOfAnswers, setNumberOfAnswers] = useState(1);
const [isOpen, setIsOpen] = useState(false)
return (
<>
<div className="flex flex-col w-full py-6 border-t-2 border-solid border-gray-200">
<header className="w-full flex flex-row justify-between py-1">
<div className="flex flex-row items-end">
<div className="flex items-center">
<strong className="text-lg mx-2">{comment.username}</strong>
{comment.isCostumer ? <p className='text-blueC0'>خریدار محصول</p> : null}
</div>
</div>
<div
className="flex flex-row divide-x divide-gray-300 divided items-center"
style={{ direction: "ltr" }}
>
<span className="px-2 text-sm text-blue-400">
{moment(comment.data).locale("fa").format("YYYY/MM/DD")}
</span>
<span className="px-2 text-sm text-blue-400">
{comment.date.getHours()}&nbsp;:&nbsp;{comment.date.getMinutes()}
</span>
</div>
</header>
<div className="flex flex-row py-4">
<div style={{ width: 60 }} className="min-h-full"></div>
<div className="flex flex-1 flex-col px-3">
<header className="w-full flex flex-row justify-between items-center">
<div className="flex flex-row items-center">
<div className='py-4 px-6 bg-blue-100 text-gray-400 rounded'><h1>برسش</h1></div>
</div>
</header>
<div className='flex items-center justify-between'>
<p className="text-gray-500 m-4">{comment.text}</p>
<Counter value={456} />
</div>
<div className="self-end mt-4">
</div>
</div>
</div>
{comment.answers.length > 0 ? comment.answers.slice(0 , numberOfAnswers).map(e => (
<div className="flex flex-row py-1">
<div style={{ width: 60 }} className="min-h-full"></div>
<div className="flex flex-1 flex-col px-3">
<header className="w-full flex flex-row justify-between items-center">
<div className="flex flex-row items-center">
<div className='py-4 px-6 bg-green-100 text-gray-400 rounded'><h1>باسخ</h1></div>
</div>
</header>
<div className='flex items-center justify-between'>
<p className="text-gray-500 m-4">{e.text}</p>
<div>
<Counter value={456} />
</div>
</div>
<div className="self-end mt-4">
</div>
</div>
</div>
)) : <header className="w-full flex flex-row justify-between items-center">
<div className="flex w-4/5 flex-row items-center">
<div className='py-4 px-6 bg-green-100 text-gray-400 mx-16 rounded'><h1>ارسال باسخ</h1></div>
</div>
</header>}
{comment.answers.length > 1 ? <div className='w-full flex justify-center'>
{open ? <Button
title={viewmore}
backgroundColor={"bg-gray-200"}
border={{
color: "#C01919",
width: "0px",
}}
width="24%"
radius={false}
onClick={isOpen ? () => {setNumberOfAnswers(1);setViewMore("مشاهده باسخ های بیشتر");setIsOpen(false);} : () => { setNumberOfAnswers(comment.answers.length);setViewMore('بستن باسخ ها');setIsOpen(true)}}
color={"text-gray-500"}
/> : null}
</div> : null}
</div>
</>
);
};
return (
<div className="w-full flex flex-col">
{comments.map((comment, index) => (
<Comment comment={comment} key={index} />
))}
</div>
);
};
export default QandA;
QandA.defaultProps = {
comments: [
{
id: 0,
pid: null,
username: "آرش سامانی",
isCostumer: true,
date: new Date(),
text: "خالد حسینی تو رمان باد بادک باز مینویسه : ﻣﺮﺩ ﺁﻫﺴﺘﻪ ﺩﺭ ﮔﻮﺵ ﻓﺮﺯﻧﺪ ﺗﺎﺯﻩ ﺑﻪ ﺑﻠﻮﻍ ﺭﺳﯿﺪﻩ ﺍﺵ ﺑﺮﺍﯼ ﭘﻨﺪ ﭼﻨﯿﻦ ﻧﺠﻮﺍ ﮐﺮﺩ : ” ﭘﺴﺮﻡ ﺩﺭ ﺯﻧﺪﮔﯽ ﻫﺮﮔﺰ ﺩﺯﺩﯼ ﻧﮑﻦ ” ﭘﺴﺮ ﻣﺘﻌﺠﺐ ﻭ ﻣﺒﻬﻮﺕ ﺑﻪ ﭘﺪﺭ ﻧﮕﺎﻩ ﮐﺮﺩ ﺑﺪﯾﻦ ﻣﻌﻨﺎ ﮐﻪ ﺍﻭ ﻫﺮﮔﺰ ﺩﺳﺖ ﮐﺞ ﻧﺪﺍﺷﺘﻪ ﭘﺪﺭ ﺑﻪ ﻧﮕﺎﻩ ﻣﺘﻌﺠﺐ ﻓﺮﺯﻧﺪ ﻟﺒﺨﻨﺪﯼ ﺯﺩ ﻭ ﺍﺩﺍﻣﻪ ",
rate: 4,
answers: [
{
text: 'لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد'
},
{
text: 'لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد'
},
{
text: 'لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد کتابهای زیادی در شصت و سه درصد گذشته حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی و فرهنگ پیشرو در زبان فارسی ایجاد کرد در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها'
},
{
text: 'لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است'
},
],
status: true,
},
{
id: 1,
pid: null,
username: "سورنا عابدی",
isCostumer: false,
date: new Date(),
text: "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد ",
rate: 4,
answers: [
],
status: true,
},
],
};

@ -0,0 +1,22 @@
export const connectToParent = (list) => {
let comments = [];
for (let item of list) {
comments.push({ ...item, child: [] });
}
for (let comment1 of comments) {
if (comment1.pid !== null) {
const index = comments.indexOf(
comments.filter((comment2) => comment2.id === comment1.pid)[0]
);
comments[index] = {
...comments[index],
child: [...comments[index].child, comment1],
};
} else {
}
}
// comments = comments.filter((comment) => comment.pid === null);
console.log(comments);
};

@ -126,8 +126,7 @@ export const ProductOverAll = ({
<ProductStatusCard />
</div>
</header>
<ProductTab />
<ProductSuggestions />
</div>
);
};

@ -1,10 +1,28 @@
import React from "react";
import ProductOverAll from "./ProductOverAll";
import ProductTab from "../../../components/ProductTab";
import ProductSuggestions from "../../../components/ProductSuggestion";
import Rate from "../Rate";
import Comment from "../Comment";
import Comments from "../../../components/Comments";
import QandA from "../../../components/QandA";
const DesktopProductLayout = () =>{
return (
<div className="w-11/12 flex flex-row overflow-y-hidden mt-3 mb-64">
<div className="w-4/5 flex flex-col overflow-y-hidden mt-3 mb-64 items-center">
<ProductOverAll />
<ProductTab />
<div className="w-full">
<ProductSuggestions />
</div>
<div className="w-2/3 my-8">
<Rate />
</div>
<div className="w-4/5">
<Comments />
<QandA />
</div>
</div>
);
};

Loading…
Cancel
Save