commit
f539a3ca05
13 changed files with 548 additions and 3 deletions
@ -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; |
After Width: | Height: | Size: 728 B |
After Width: | Height: | Size: 829 B |
After Width: | Height: | Size: 119 KiB |
After Width: | Height: | Size: 981 B |
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,135 @@ |
|||||||
|
|
||||||
|
import React from "react"; |
||||||
|
import { useState } from "react"; |
||||||
|
|
||||||
|
const ProductDescription = ({ |
||||||
|
navTitles, |
||||||
|
items, |
||||||
|
addToCart |
||||||
|
}) =>{ |
||||||
|
const [name, setName] = useState(navTitles[0].name); |
||||||
|
const [type, setType] = useState([]); |
||||||
|
return( |
||||||
|
<> |
||||||
|
<div className="flex w-full rounded bg-gray-200 justify-center mt-6 "> |
||||||
|
<ul className="w-full flex justify-center"> |
||||||
|
{navTitles.map(item => <li key={`NavTitle_${item.id}`}
|
||||||
|
className={`p-6 mx-4 cursor-pointer
|
||||||
|
${type[item.id] ? 'border-0 border-b-4 border-solid border-blue-500' : null}` |
||||||
|
}
|
||||||
|
onClick={() => {
|
||||||
|
// type[item.id] = type
|
||||||
|
// type[item.id] = !type[item.id]
|
||||||
|
setName(item.name) |
||||||
|
// setType(type)
|
||||||
|
// console.log(type)
|
||||||
|
// console.log(item.id)
|
||||||
|
// console.log(type[item.id])
|
||||||
|
|
||||||
|
}}> |
||||||
|
{item.title}</li>)} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
<div className="flex w-full "> |
||||||
|
<div className="flex-1 "> |
||||||
|
|
||||||
|
{items.map(e => (
|
||||||
|
e.name == name ? |
||||||
|
e.items.map(item => ( |
||||||
|
<ul className="flex w-full flex-1 my-2 items-center"> |
||||||
|
|
||||||
|
{item.title ?
|
||||||
|
<li className="py-4 px-8 min-w-md bg-gray-200 ml-4 text-blueC0" style={{minWidth: '300px'}}>{item.title}</li> : null} |
||||||
|
<li className="py-4 px-8 min-w-md bg-gray-200 ml-4 w-full">{item.description}</li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
)) : null |
||||||
|
|
||||||
|
|
||||||
|
))}
|
||||||
|
</div> |
||||||
|
<div className="my-2"> |
||||||
|
{addToCart} |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
</> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default ProductDescription; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ProductDescription.defaultProps = { |
||||||
|
navTitles: [ |
||||||
|
{ |
||||||
|
id: 0, |
||||||
|
title: 'مشخصات', |
||||||
|
isActive: true, |
||||||
|
name: 'moshakhasat' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 1, |
||||||
|
title: 'نقد و بررسی', |
||||||
|
isActive: false, |
||||||
|
name: 'review' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 2, |
||||||
|
title: 'برسش و باسخ', |
||||||
|
isActive:false |
||||||
|
}, |
||||||
|
], |
||||||
|
items: [ |
||||||
|
{ |
||||||
|
name: 'moshakhasat', |
||||||
|
items: [ |
||||||
|
{ |
||||||
|
title : 'وزن کتاب', |
||||||
|
description: '۱ کیلوگرم' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title : 'تعداد صفحات', |
||||||
|
description: '400 صفحه' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title : 'نوع کاغذ', |
||||||
|
description: 'گلاسه' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title : 'شماره شابک', |
||||||
|
description: '1225548218000005818765' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title : 'انتشارات', |
||||||
|
description: 'رزمندگان' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title : 'نویسنده و یا معلف', |
||||||
|
description: 'یک نویسنده گمنام' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title : 'قطع', |
||||||
|
description: 'خشتی' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title : 'سال انتشار', |
||||||
|
description: '1399' |
||||||
|
}, |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'review', |
||||||
|
items: [{ |
||||||
|
description: 'لورم ایبسوم' |
||||||
|
}] |
||||||
|
} |
||||||
|
] |
||||||
|
|
||||||
|
} |
@ -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()} : {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); |
||||||
|
}; |
Loading…
Reference in new issue