لینک‌های مفید برای شرکت در مسابقه:

در طول مسابقه می‌توانید سؤالات خود را از قسمت «سؤال بپرسید» مطرح کنید.

این که ناقصه!


ظاهر برنامه چند وقت پیش عرفان پروژه‌ای را قبول کرد؛ پروژه‌ای که در آن باید صفحه‌ی یک مقاله را با ری‌اکت طراحی می‌کرد؛ صفحه‌ای که از چهار قسمت اصلی تشکیل شده که به شرح زیر است:

  1. عنوان و توضیحات مقاله
  2. سیستم امتیازدهی به مقاله
  3. سیستم ثبت نظر
  4. قسمت نمایش نظرات به‌صورت تودرتو

متأسفانه در اواسط پروژه بود که عرفان درگیر ویروس کرونا شد و پروژه ناقص ماند، اما از آن‌جایی که عرفان روی قولی که می‌دهد بسیار حساس است، از شما خواسته تا قسمت‌هایی از پروژه را که باقی مانده کامل کنید تا مبادا بد قول شود و بتواند پروژه را سر وقت تحویل دهد.

جزئیات پروژه🔗

پروژه‌ی اولیه را از این لینک دانلود کنید.

ساختار فایل‌های پروژه
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
Plain text
راه‌اندازی پروژه
  • پروژه‌ی اولیه را دانلود و از حالت فشرده خارج کنید.

  • اجرای دستور npm i پکیج های مورد نیاز را نصب کنید.

  • با اجرای دستور npm run server سرور را اجرا کنید.

  • با اجرای دستور npm start پروژه را اجرا کنید.

قسمت‌های باقی‌مانده از پروژه که باید پیاده‌سازی شوند🔗

پاسخ به نظر دیگران🔗

در کامپوننت Comment دکمه‌ای تحت عنوان reply وجود دارد که با کلیک کردن روی آن به وضعیت پاسخ می‌رویم. در وضعیت پاسخ، اتفاقاتی رخ می دهد که به شرح زیر است:

  1. کاربر باید به المانی با کلاس ac-wrapper اسکرول شود. این المان در فایل AddComment وجود دارد.
  2. در فایل AddComment یک تگ h2 وجود دارد که محتوای آن در وضعیت پاسخ باید برابر باشد با:
Write your comment in response to {name}:
JavaScript

که {name} برابر است با نام فردی که قرار است به او پاسخ داده شود.

و در وضعیت ثبت نظر باید برابر باشد با:

Write your comment:
JavaScript
  1. در وضعیت پاسخ باید بعد از دکمه‌ی Send در فایل AddComment دکمه‌ای تحت عنوان Cancel اضافه شود که در صورت کلیک کردن روی این دکمه، باید از وضعیت پاسخ به وضعیت ثبت نظر برگردیم.

  2. اگر در وضعیت ثبت نظر باشیم، در فایل AddComment بعد از input با نوع email باید کامپوننت SelectBox فراخوانی شود، اما اگر در وضعیت پاسخ باشیم، این کامپوننت نباید در صفحه وجود داشته باشد.

انتخاب topic🔗

مقالات موضوعات مختلفی را شامل می‌شوند. کاربر هنگام ثبت نظر باید topic یا موضوعی را مشخص کند. برای این کار، عرفان سروری آماده کرده است که یک رشته دریافت می‌کند و بین topic های موجود جست‌وجو می‌کند و لیست topic هایی که رشته‌ی ارسال‌شده در آن‌ها وجود دارد را بر می‌گرداند. برای مثال اگر topic ها در سرور به‌صورت زیر باشند:

php , python , java , c++ , Go
Plain text

اگر حرف p برای سرور ارسال شود، سرور لیست زیر را برمی‌گرداند:

{
    "data": {
        "matchedTechs": [
            { "id": 1, "name": "php" },
            { "id": 2, "name": "python" }
        ]
    },
    "status": "success"
}
JSON

در فایل ‍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";
CSS

لیست topic ها نمایش داده نمی‌شود و dropdown در وضعیت بسته است و اگر این استایل ها را نداشته باشد، dropdown در وضعیت باز است و لیست topic ها در صفحه نمایش داده می شود.

در صورتی که لیست topic ها خالی باشد، dropdown باید بسته باشد.

در صورتی که لیست topic ها خالی نباشد، باید لیست را در المان div با کلاسc-selectbox به‌صورت زیر رندر کنید:

<div className="item">
    <label htmlFor={آیدی تاپیک}>{نام تاپیک}</label>
    <input type="radio" name="" id={آیدی تاپیک} />
</div>
React JSX

با کلیک بر روی المان 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 }
]
JavaScript

در صورتی که مقدار 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"
}
JSON

پس از دریافت پیام بالا، باید مقدار message را به‌صورت یک toast نمایش دهید. برای این کار، عرفان به پیشنهاد مهیار از پکیج react-toastify استفاده کرده است. البته کدهای این قسمت را نیز در اختیار شما قرار داده است. کافی است در صورت دریافت پاسخ موفقیت‌آمیز، از تکه‌کد زیر استفاده کنید:

toast.success(پیامی که از سرور دریافت کرده اید, {
    position: "top-left",
});
JavaScript

در صورت fail شدن درخواست، پاسخ سرور به‌صورت زیر خواهد بود:

{
    "message": "Rating registering failed, try again.",
    "rate": آخرین امتیازی که در سرور ثبت شده است,
    "status": "error"
}
JSON

مقدار rate برابر با آخرین امتیاز ثبت‌شده‌ی کاربر است. شما باید این مقدار را به تابع stepBackward ارسال کنید.

به دلیل این که سرور تأخیر دارد، ما در زمان تآخیر باید امتیازی که کاربر ثبت کرده است را آپدیت و رندر کنیم، اما به محض این که پاسخ از سرور دریافت شود، در صورتی که درخواست fail شده باشد، باید سیستم rating را مجدد آپدیت کنیم و به rate قبلی برگردیم (منظور آخرین امتیازی است که کاربر وارد کرده و در سرور ثبت شده). به این تکنیک، optimistic rendering گفته می‌شود. تابع stepBackward در واقع قرار است این کار را برای ما هندل کند. پس از فراخوانی تابع stepBackward باید مجدداً یک toast به کاربر نمایش دهید. برای این کار، از تکه‌کد زیر استفاده کنید:

toast.error(پیامی که از سرور دریافت کرده اید, {
    position: "top-left",
});
JavaScript

تابع 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
Plain text

آن‌چه باید آپلود کنید🔗

پس از پیاده‌سازی موارد خواسته‌شده، پوشه‌ی src را زیپ کرده و آپلود کنید.

ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.