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

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

پیندو


پروژه اولیه🔗

پروژه‌ی اولیه را از این لینک دانلود کنید. ساختار فایل‌های این پروژه به صورت زیر است.

ساختار پروژه
pindo
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   └── logo512.png
├── src
│   ├── assets
│   │   └── font
│   │       └── Vazir.ttf
│   ├── components
│   │   ├── Button
│   │   │   ├── Button.css
│   │   │   └── index.jsx
│   │   ├── Checkbox
│   │   │   └── index.jsx
│   │   ├── CitySelector
│   │   │   ├── CitySelectorItem.jsx
│   │   │   └── index.jsx
│   │   ├── Dropdown
│   │   │   └── index.jsx
│   │   ├── Error
│   │   │   └── index.jsx
│   │   ├── TextInput
│   │   │   └── index.jsx
│   │   ├── Textarea
│   │   │   └── index.jsx
│   │   └── FormItem.jsx
│   ├── constants
│   │   ├── Errors.js
│   │   └── FormType.js
│   ├── data
│   │   ├── cities.js
│   │   └── formData.js
│   ├── App.css
│   ├── App.jsx
│   ├── index.css
│   └── index.js
└── package.json
Plain text
راه‌اندازی پروژه

برای اجرای پروژه، باید NodeJS و npm را از قبل نصب کرده باشید.

  • ابتدا پروژه‌ی اولیه را دانلود و از حالت فشرده خارج کنید.
  • در پوشه‌ی pindo ، دستور npm install را برای نصب نیازمندی‌ها اجرا کنید.
  • در همین پوشه، دستور npm start را برای راه‌اندازی پروژه اجرا کنید.
  • پس از انجام موفق این مراحل، با مراجعه به آدرس http://localhost:3000/ می‌توانید نتیجه را ببینید.

جزئیات🔗

ظاهر کلی برنامه به‌این صورت است:

ظاهر برنامه

یکی از قسمت‌های اصلی پروژه پیندو ایجاد آگهی است. کاربران در دسته‌بندی‌های مختلفی می‌توانند برای کالای خود آگهی ایجاد کنند. برای مثال فرم ایجاد آگهی برای گوشی موبایل با ظروف آشپزخانه متفاوت است. به‌ همین جهت فرم ایجاد آگهی باید به صورت داینامیک باشد. در این سوال از شما می‌خواهیم این فرم‌های داینامیک را بسازید.

اِلِمان‌های فرم در یک آرایه قرار دارد. ساختار این آرایه به شکل زیر است:

{
  "type": string,
  "required": boolean | undefined,
  "name": string,
  "label": string,
  "options": { "title": string, "value": number }[],
  "dependency": {
    "show": { "name": string, "value": string | boolean | number },
    "required": { "name": string, "value": string | boolean | number },
  } | undefined,
}
JSON

فیلد type🔗

این فیلد نشان‌دهنده‌ی نوع اِلمان است.

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

const FormType = {
  TEXT: "text",
  DROPDOWN: "dropdown",
  TEXTAREA: "textarea",
  CHECKBOX: "checkbox",
  CITY: "city",
};
JavaScript

فیلد required🔗

این فیلد نشان می‌دهد که آیا تکمیل این المان اجباری خواهد بود یا خیر. درصورتی که این فیلد true باشد، کاربر باید حتما برای این فیلد مقداری را وارد کند. این فیلد می‌تواند خالی باشد و این به معنای غیراجباری بودن این فیلد است.

فیلد name🔗

این فیلد نشان‌دهنده‌ی کلید اصلی آن المان است. در هنگام ساخت داده‌های ورودی کاربر، مقدار کلید برابر این فیلد است.

فیلد label🔗

این فیلد مشخص‌کننده‌ی برچسب (لیبل) المان است.

فیلد options🔗

در صورتی که type یک المان برابر FormType.DROPDOWN باشد، مقادیری قابل انتخاب در فرم select در این فیلد قرار می‌گیرد.

فیلد dependency🔗

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

  • وابستگی show: به این معنا است که نمایش این فیلد به مقدار یک فیلد دیگر وابسته است.
  • وابستگی required: به این معنا است که اجباری بودن این فیلد به مقدار یک فیلد دیگر وابسته است.

هر کدام از این وابستگی‌ها به شکل زیر مشخص می‌شوند:

{ "name": string, "value": string | boolean | number }
JSON

که name نشان‌دهنده‌ی فیلدی است که به آن وابسته است و value نشان‌دهنده‌ی شرط وابستگی است. در صورتی که مقدار فیلد name برابر value بود، شرط وابستگی برقرار است.

برای مثال در داده‌‌ی زیر فیلد productIssues به فیلد productStatus وابسته است. در صورتی که مقدار انتخابی در productStatus برابر 4 باشد (یعنی مقدار انتخابی خراب باشد)، این فیلد باید (productIssues) نمایش داده شود. هم‌چنین اجباری‌بودن فیلد city به مقدار فیلد delivery بستگی دارد و مقدار این فیلد باید true باشد. دقت کنید این فیلد باید نمایش داده شود ولی اجباری‌بودن آن به فیلد دیگری بستگی دارد.

[
  {
    "type": "dropdown",
    "name": "productStatus",
    "label": "وضعیت کالا",
    "options": [
      { "title": "نو", "value": 1 },
      { "title": "در حد نو", "value": 2 },
      { "title": "دست دوم", "value": 3 },
      { "title": "خراب", "value": 4 },
    ],
  },
  {
    "type": "textarea",
    "name": "productIssues",
    "label": "مشکلات کالا",
    "dependency": {
      "show": { "name": "productStatus", "value": 4 },
    },
  },
  {
    "type": "checkbox",
    "name": "delivery",
    "label": "از سیستم دلیوری استفاده خواهم کرد",
  },
  {
    "type": "city",
    "name": "cityId",
    "label": "محل آگهی",
    "dependency": {
      "required": { "name": "delivery", "value": true },
    },
  },
];
JSON

مواردی که باید در این سوال رعایت کنید:🔗

  • شما باید برنامه‌ای بنویسید که لیست فیلد‌ها را دریافت کند و به این شکل ساختاری نمایش دهد.
  • فرم نهایی در صورتی باید submit شود که تمام شرایط لازم در آن رعایت شده باشد (تمام فیلدهای اجباری وارد شده باشند).
  • مقادیر وارد شده باید به تابع onSubmit پاس داده شود. (این تابع به شکل prop به کامپوننت داده می‌شود)
  • در صورتی که یک فیلد اجباری پر نشده بود، باید برای آن فیلد خطا نمایش داده شود (کاپوننت آن آورده شده است و فقط لازم است برحسب شرایط از آن استفاده کنید).
  • در صورتی که یک فیلد غیراجباری پر نشده بود، باید برای آن فیلد مقدار undefiend به تابع onSubmit فرستاده شود.

تغییرات لازم برای هر فایل:🔗

  • فایل App.jsx: منطق اصلی کد شما در این فایل قرار می‌گیرد. در این فایل شما props را به‌عنوان ورودی می‌گیرید.
  • onSubmit: زمانی که فرم بدون خطا بود، به این تابع مقادیر وارد شده را به‌عنوان پارامتر ورودی بفرستید.
  • fields: فیلد‌های فرم در این prop قرار می‌گیرد.
  • فایل FormItem.jsx: در این کامپوننت شما براساس type هر المان باید از یکی کامپوننت‌های آورده شده، استفاده کنید.

شما لازم است براساس هر آیتم در fields از این کامپوننت استفاده کنید.

نکات🔗

  • حتما از کامپوننت‌های داخل پروژه استفاده شود، در غیر این صورت نمره سوال را نخواهید گرفت.
  • شما تنها مجاز به اعمال تغییرات در فایل‌های App.jsx و FormItem.jsx و package.json هستید.
  • به کامنت‌های داخل فایل‌ها دقت کنید.
  • استفاده از کتابخانه‌های خارجی مجاز است. (در پروژه اولیه کتاب‌خانه‌ی react-hook-form قرار داده شده است)
  • برای ارسال پاسخ کل پروژه را zip کرده و ارسال کنید. دقت کنید که پوشه‌ی node_modules در فایل ارسالی نباشد.
ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.