پروژه اولیه
پروژهی اولیه را از این لینک دانلود کنید. ساختار فایلهای این پروژه به صورت زیر است.
ساختار پروژه
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
راهاندازی پروژه
برای اجرای پروژه، باید 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,
}
فیلد type
این فیلد نشاندهندهی نوع اِلمان است.
هر المان فرم میتواند یکی از مقادیر type زیر را داشته باشد:
const FormType = {
TEXT: "text",
DROPDOWN: "dropdown",
TEXTAREA: "textarea",
CHECKBOX: "checkbox",
CITY: "city",
};
فیلد required
این فیلد نشان میدهد که آیا تکمیل این المان اجباری خواهد بود یا خیر.
درصورتی که این فیلد true
باشد، کاربر باید حتما برای این فیلد مقداری را وارد کند.
این فیلد میتواند خالی باشد و این به معنای غیراجباری بودن این فیلد است.
فیلد name
این فیلد نشاندهندهی کلید اصلی آن المان است. در هنگام ساخت دادههای ورودی کاربر، مقدار کلید برابر این فیلد است.
فیلد label
این فیلد مشخصکنندهی برچسب (لیبل) المان است.
فیلد options
در صورتی که type یک المان برابر FormType.DROPDOWN باشد، مقادیری قابل انتخاب در فرم select در این فیلد قرار میگیرد.
فیلد dependency
هر المان میتواند به المان دیگری وابستگی داشته باشد. این موضوع در این فیلد مشخص میشود. در صورتی که این فیلد وجود نداشت، به این معنا است که این فیلد به فیلد دیگری وابستگی ندارد. وابستگی به دو شکل وجود دارد:
- وابستگی show: به این معنا است که نمایش این فیلد به مقدار یک فیلد دیگر وابسته است.
- وابستگی required: به این معنا است که اجباری بودن این فیلد به مقدار یک فیلد دیگر وابسته است.
هر کدام از این وابستگیها به شکل زیر مشخص میشوند:
{ "name": string, "value": string | boolean | number }
که 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 },
},
},
];
مواردی که باید در این سوال رعایت کنید:
- شما باید برنامهای بنویسید که لیست فیلدها را دریافت کند و به این شکل ساختاری نمایش دهد.
- فرم نهایی در صورتی باید 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 در فایل ارسالی نباشد.
ارسال پاسخ برای این سؤال