چند وقت پیش عرفان پروژهای را قبول کرد؛ پروژهای که در آن باید صفحهی یک مقاله را با ریاکت طراحی میکرد؛ صفحهای که از چهار قسمت اصلی تشکیل شده که به شرح زیر است:
- عنوان و توضیحات مقاله
- سیستم امتیازدهی به مقاله
- سیستم ثبت نظر
- قسمت نمایش نظرات بهصورت تودرتو
متأسفانه در اواسط پروژه بود که عرفان درگیر ویروس کرونا شد و پروژه ناقص ماند، اما از آنجایی که عرفان روی قولی که میدهد بسیار حساس است، از شما خواسته تا قسمتهایی از پروژه را که باقی مانده کامل کنید تا مبادا بد قول شود و بتواند پروژه را سر وقت تحویل دهد.
جزئیات پروژه
پروژهی اولیه را از این لینک دانلود کنید.
ساختار فایلهای پروژه
comments
├── package.json
├── package-lock.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── README.md
├── server
│ ├── app.js
│ ├── posts.json
│ └── techs.json
└── src
├── App.css
├── App.jsx
├── assets
│ └── avatar.png
├── components
│ ├── AddComment.jsx
│ ├── Comment.jsx
│ ├── Post.jsx
│ ├── Rate.jsx
│ └── SelectBox.jsx
├── container
│ └── Comments.jsx
├── data
│ └── data.js
├── index.js
└── __tests__
└── sample.test.js
راهاندازی پروژه
-
پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
-
اجرای دستور
npm i
پکیج های مورد نیاز را نصب کنید. -
با اجرای دستور
npm run server
سرور را اجرا کنید. -
با اجرای دستور
npm start
پروژه را اجرا کنید.
قسمتهای باقیمانده از پروژه که باید پیادهسازی شوند
پاسخ به نظر دیگران
در کامپوننت Comment
دکمهای تحت عنوان reply
وجود دارد که با کلیک کردن روی آن به وضعیت پاسخ میرویم. در وضعیت پاسخ، اتفاقاتی رخ می دهد که به شرح زیر است:
- کاربر باید به المانی با کلاس
ac-wrapper
اسکرول شود. این المان در فایلAddComment
وجود دارد. - در فایل
AddComment
یک تگh2
وجود دارد که محتوای آن در وضعیت پاسخ باید برابر باشد با:
Write your comment in response to {name}:
که {name}
برابر است با نام فردی که قرار است به او پاسخ داده شود.
و در وضعیت ثبت نظر باید برابر باشد با:
Write your comment:
-
در وضعیت پاسخ باید بعد از دکمهی
Send
در فایلAddComment
دکمهای تحت عنوانCancel
اضافه شود که در صورت کلیک کردن روی این دکمه، باید از وضعیت پاسخ به وضعیت ثبت نظر برگردیم. -
اگر در وضعیت ثبت نظر باشیم، در فایل
AddComment
بعد ازinput
با نوعemail
باید کامپوننتSelectBox
فراخوانی شود، اما اگر در وضعیت پاسخ باشیم، این کامپوننت نباید در صفحه وجود داشته باشد.
انتخاب topic
مقالات موضوعات مختلفی را شامل میشوند. کاربر هنگام ثبت نظر باید topic یا موضوعی را مشخص کند. برای این کار، عرفان سروری آماده کرده است که یک رشته دریافت میکند و بین topic های موجود جستوجو میکند و لیست topic هایی که رشتهی ارسالشده در آنها وجود دارد را بر میگرداند. برای مثال اگر topic ها در سرور بهصورت زیر باشند:
php , python , java , c++ , Go
اگر حرف p
برای سرور ارسال شود، سرور لیست زیر را برمیگرداند:
{
"data": {
"matchedTechs": [
{ "id": 1, "name": "php" },
{ "id": 2, "name": "python" }
]
},
"status": "success"
}
در فایل components/SelectBox
یک input
با کلاس tpc
وجود دارد. در صورت تغییر value
این input
، باید یک درخواست GET به آدرس http://127.0.0.1:8000/
ارسال شود و مقدار input
در query string با کلید search
ارسال کنید تا لیست topic ها دریافت شوند.
عرفان برای نمایش topic ها یک المان div
با کلاس c-selectbox
ساخته است. این المان به نحوی طراحی و استایلدهی شده است که شبیه به یک dropdown باشد. اگر استایل های زیر را داشته باشد:
padding: 0;
height: 0;
overflow: "hidden";
لیست topic ها نمایش داده نمیشود و dropdown در وضعیت بسته است و اگر این استایل ها را نداشته باشد، dropdown در وضعیت باز است و لیست topic ها در صفحه نمایش داده می شود.
در صورتی که لیست topic ها خالی باشد، dropdown باید بسته باشد.
در صورتی که لیست topic ها خالی نباشد، باید لیست را در المان div
با کلاسc-selectbox
بهصورت زیر رندر کنید:
<div className="item">
<label htmlFor={آیدی تاپیک}>{نام تاپیک}</label>
<input type="radio" name="" id={آیدی تاپیک} />
</div>
با کلیک بر روی المان div
با کلاس item
که رندر کردهاید، اتفاقات زیر باید رخ دهد:
ابتدا باید dropdown بسته شود و سپس باید نام کامل آن topic به عنوان مقدار input
با کلاس tpc
قرار بگیرد
دقت کنید در زمانی که لیست تاپیک ها خالی نیست و ما در حال نمایش topic ها هستیم در صورتی که کاربر بهصورت کلی روی body
کلیک کند، باید dropdown بسته شود و مقدار input
با کلاس tpc
تغییر نکند.
امتیازدهی
در این بخش از سؤال، شما باید سیستم امتیازدهی به مقاله را پیادهسازی کنید. در فایل Rate.jsx
یک استیت به نام star
وجود دارد که مقدار اولیهی آن به صورت زیر است:
[
{ id: 1, hover: false, clicked: false },
{ id: 2, hover: false, clicked: false },
{ id: 3, hover: false, clicked: false },
{ id: 4, hover: false, clicked: false },
{ id: 5, hover: false, clicked: false }
]
در صورتی که مقدار hover
و clicked
برابر با true
باشد، ستارههای تو پر و در غیر اینصورت، ستارههای تو خالی نمایش داده میشوند. در این بخش چهار تابع داریم که دو تا از آنها بهصورت کامل نوشته شده و دو تابع را باید شما پیادهسازی کنید. عملکرد دو تابعی که به صورت کامل از قبل نوشته شده بهشرح زیر است:
تابع hoverHandler
این تابع رویداد onMouseEnter
روی ستارهها را هندل میکند، بهطوری که یک شناسه دریافت میکند و مقدار hover
هر آبجکتی که شناسهی آنها از نظر عددی کوچکتر از شناسهی دریافتی است را برابر با true
میکند. برای مثال، فرض کنید کاربر ستارهی چهارم را hover کرده است. ما باید ستارههایی با شناسهی 1
تا 4
را آپدیت کنیم و مقدار hover
آنها را true
کنیم.
تابع blurHandler
این تابع رویداد onMouseLeave
را روی ستارهها هندل میکند، بهطوری که مقدار hover
هر آبجکت را آپدیت کرده و آن را برابر با false
قرار میدهد.
و اما دو تابعی که شما باید آنها را کامل کنید:
تابع submitRateHandler
این تابع در قدم اول مانند تابع hoverHandler
کار می کند، با این تفاوت که به جای true
کردن مقدار hover
هر آبجکت، باید مقدار clicked
هر آبجکت را true
کند. در ادامه، باید یک درخواست از نوع PATCH به آدرس http://127.0.0.1:8000/posts/
ارسال کند و در بدنهی درخواست، شناسهی آخرین آبجکتی که ویژگی clicked
آن برابر با true
شده را به عنوان rate
به صورت JSON به سرور ارسال کند.
متأسفانه در حال حاضر سرور خراب است و عرفان از دوستش سینا خواسته تا سرور را درست کند، اما سینا در سفر به سر میبرد و شما باید با همین سرور خراب کار کنید! اشکال سرور این است که با احتمال ۵۰ درصد، rate
کاربران را ثبت میکند و با احتمال ۵۰ درصد، درخواست شما با خطا مواجه میشود. علاوه بر این، سرور یک تأخیر یک ثانیه ای نیز دارد. اگر درخواست شما با موفقیت ثبت شود پیام سرور به شما به صورت زیر خواهد بود:
{
"message": "Your rate for this post has been registered.",
"status": "success"
}
پس از دریافت پیام بالا، باید مقدار message
را بهصورت یک toast نمایش دهید. برای این کار، عرفان به پیشنهاد مهیار از پکیج react-toastify
استفاده کرده است. البته کدهای این قسمت را نیز در اختیار شما قرار داده است. کافی است در صورت دریافت پاسخ موفقیتآمیز، از تکهکد زیر استفاده کنید:
toast.success(پیامی که از سرور دریافت کرده اید, {
position: "top-left",
});
در صورت fail شدن درخواست، پاسخ سرور بهصورت زیر خواهد بود:
{
"message": "Rating registering failed, try again.",
"rate": آخرین امتیازی که در سرور ثبت شده است,
"status": "error"
}
مقدار rate
برابر با آخرین امتیاز ثبتشدهی کاربر است. شما باید این مقدار را به تابع stepBackward
ارسال کنید.
به دلیل این که سرور تأخیر دارد، ما در زمان تآخیر باید امتیازی که کاربر ثبت کرده است را آپدیت و رندر کنیم، اما به محض این که پاسخ از سرور دریافت شود، در صورتی که درخواست fail شده باشد، باید سیستم rating را مجدد آپدیت کنیم و به rate
قبلی برگردیم (منظور آخرین امتیازی است که کاربر وارد کرده و در سرور ثبت شده). به این تکنیک، optimistic rendering گفته میشود. تابع stepBackward
در واقع قرار است این کار را برای ما هندل کند. پس از فراخوانی تابع stepBackward
باید مجدداً یک toast به کاربر نمایش دهید. برای این کار، از تکهکد زیر استفاده کنید:
toast.error(پیامی که از سرور دریافت کرده اید, {
position: "top-left",
});
تابع stepBackward
این تابع یک rate دریافت میکند و باید استیت مربوط به ستارهها را آپدیت کند، به طوری که مقدار clicked
مربوط به المانهای دارای شناسههای کوچکتر یا مساوی rate
را true
کند و مقدار hover
آنها را false
کند. برای مثال، استیت ستارهها در هر وضعیتی که باشد، در صورت fail شدن درخواست اگر سرور مقدار rate
را 3
برگرداند، باید آبجکتهایی با شناسههای 1
تا 3
طوری آپدیت شوند که مقدار clicked
شان true
و مقدار hover
شان false
شود.
توجه: شما تنها مجاز به اعمال تغییرات در فایلهای زیر هستید:
src/App.jsx
src/components/AddComment.jsx
src/components/Comment.jsx
src/components/Rate.jsx
src/components/SelectBox.jsx
آنچه باید آپلود کنید
پس از پیادهسازی موارد خواستهشده، پوشهی src
را زیپ کرده و آپلود کنید.
ارسال پاسخ برای این سؤال