فایل پروژه را میتوانید از طریق این این لینک دانلود کنید.
ساختار پروژه به شکل زیر است:
فایلی که آپلود خواهید کرد باید دارای فرمت .zip
باشد و دارای ساختار زیر باشد:
موفق باشید 🌟
فایلِ پروژه را میتوانید از طریق این این لینک دانلود کنید.
ساختار پروژه به شکلِ زیر است:
همانطور که مشاهده میکنید، همهی پورتها شامل یک مقدار مشخص هستند که در فایلِ index.html
میتوانید تگهای مربوطه برا ببینید.
در کنارِ هر عدد، یک آیکونِ ویرایش (همان مداد) مشاهده میکنید که وقتی روی آن کلیک میکنیم، تگی که مقدار در آن ذخیره شده بود باید از دیدِ کاربر محو شده و بهجای آن، یک input نمایش داده شود که مقدارِ آن، همان مقدارِ موجود در تگِ مربوطه بوده؛ همچنین یک دکمهی «ثبت» هم در زیرِ هر input قرار دارد.
حالا با وارد کردنِ مقدارِ جدید در input و زدنِ دکمهی ثبت، input محو شده و دوباره همان تگی که وظیفهی نمایش مقدار را داشت، نمایش داده میشود.
فایلی که آپلود خواهید کرد باید دارای فرمت .zip
باشد و دارای ساختارِ زیر باشد:
موفق باشید 🌟
فایل پروژه را میتوانید از طریق این این لینک دانلود کنید.
ساختار پروژه به شکل زیر است:
ویژگی | > 800px | ≤ 800px |
---|---|---|
display |
- | flex |
flex-direction |
- | column |
gap |
3px |
10px |
padding |
8px |
5px |
flex |
1 |
1 |
ویژگی | > 800px | ≤ 800px |
---|---|---|
display |
flex | flex |
flex-direction |
- | column |
justify-content |
center |
center |
align-items |
center |
center |
.box1 .sub-box
(بالای 800px)🔗بخش | ویژگی | مقدار |
---|---|---|
فرزند اول | flex |
1 |
- | height |
300px |
فرزند دوم | flex |
1 |
- | height |
200px |
.box1 .sub-box1
( زیر 800px)🔗ویژگی | مقدار |
---|---|
background-color |
rgb(255, 0, 0) |
border-radius |
12px |
width |
250px |
.box1 .sub-box2
(زیر 800px)🔗ویژگی | مقدار |
---|---|
background-color |
rgb(0, 0, 255) |
border-radius |
10px |
width |
150px |
ویژگی | > 800px | ≤ 800px |
---|---|---|
display |
flex |
flex |
.left-nested-box
و .right-nested-box
🔗ویژگی | > 800px | ≤ 800px |
---|---|---|
padding |
10px / 20px |
همان مقدار |
display |
flex |
همان مقدار |
flex-direction |
column |
همان مقدار |
gap |
10px / 2px |
همان مقدار |
border-radius |
فقط در ≤800px (8px برای همه عناصر) |
8px |
ویژگی | > 800px | ≤ 800px |
---|---|---|
display |
flex |
flex |
flex-direction |
- |
column |
.box3 .small-box
🔗موقعیت در DOM | ویژگی | > 800px | ≤ 800px |
---|---|---|---|
همه .small-box |
flex |
1 |
1 |
فرزند اول | width |
– | 50px |
- | border-radius |
– | 5px |
- | background |
– | #4682b4 |
فرزند سوم | width |
– | 200px |
- | border-radius |
– | 20px |
- | background |
– | #4682b4 |
big-box
🔗ویژگی | > 800px | ≤ 800px |
---|---|---|
flex |
2 |
1 |
height |
169px |
- |
width |
- | 100px |
border-radius |
- | 10px |
background |
- | #ffa07a |
ویژگی | > 800px | ≤ 800px |
---|---|---|
تعداد ستون های هر سطح |
1 |
4 |
کلاس | > 800px | ≤ 800px |
---|---|---|
hamburger |
معلوم نباشد |
معلوم باشد |
nav-links |
معلوم باشد |
معلوم نباشد |
فایلی که آپلود خواهید کرد باید دارای فرمت .zip
باشد و دارای ساختار زیر باشد:
موفق باشید 🌟
فایل پروژه را میتوانید از طریق این این لینک دانلود کنید.
ساختار پروژه به شکل زیر است:
getProduct.js
، تابعی با همین نام وجود دارد که یک Promise برمیگرداند، که شامل مشخصات محصولات است.showToast
را باید با هدف نمایش toaster به کاربر کامل کنید. تگ مورد نظر که دارای آیدی toast
است را از فایل HTML بهدست بیاورید.renderProduct
باید اطلاعات محصول را در فرمت زیر و در تگی که دارای آیدی product-card
است قرار دهد:تصویر محصول کامل به شکل زیر است :
renderEror
در صورتی که دریافت اطلاعات محصول با مشکل مواجه شد، محتوای داخلی product-card
به این شکل خواهد بود:retry-btn
وجود دارد که باید برای آن یک event کلیک تعریف کنید تا با کلیک روی آن، سعی دوباره برای دریافت اطلاعات انجام شود (تابع نوشتهشده برای این کار را call کنید).loadProduct
را باید طوری کامل کنید، که هنگام لودینگ، محتوای زیر در product-card
نمایش داده شود:همچنین در این تابع باید تلاش برای دریافت اطلاعات انجام شود. در صورت موفقیت، باید renderProduct
را call کنید و در صورت شکست، showToast
را نمایش دهید و همچنین renderError
را فراخوانی کنید.
show
و برای محو کردن آنها از کلاس hidden
که در فایل CSS از قبل نوشته شدهاند استفاده بکنید.<!-- -->
کامنت HTML را مشاهده میکنید که باید در آن قسمتها اطلاعات مربوط به محصول را قرار دهید.toaster
نمایش داده شود.getProduct.js
از import
استفاده کنید.فایلی که آپلود خواهید کرد باید دارای فرمت .zip
باشد و دارای ساختار زیر باشد:
موفق باشید 🌟
فایل پروژه را میتوانید از طریق این این لینک دانلود کنید.
ساختار پروژه به شکل زیر است:
در فایل data.js
، تابعی وجود دارد که اطلاعات لیستی از ماشینها در آن موجود است.
۱. اینپوت، سلکتور و تیبل را میتوانید از طریق آیدیهای زیر بدست آورید:
searchInput
yearFilter
carsTable
۲. این خط را مشاهده کنید:
با ادامه دادن آن، اطلاعات ماشینها را بهدست آورید.
۳. تابع renderCars
را بهگونهای پیادهسازی کنید که:
emptyListString
بهعنوان محتوای بدنهٔ تیبل نمایش داده شود.createYearFilterList
را طوری کامل کنید که : ۵. تابع applyFilters
را طوری کامل کنید که:
۱. هر زمان که کاربر شروع به تایپ کرد یا سالی را انتخاب نمود، فارغ از بازههای زمانی، باید فوراً اسپینر لودینگ با استفاده از تابع showSpinner
نمایش داده شود.
۲. بازههای زمانی ذکرشده حتماً باید رعایت شوند. در غیر این صورت، هدف برنامه محقق نخواهد شد.
۳. تغییرات فیلترها فقط باید در بدنهٔ تیبل اعمال شوند.
فایلی که آپلود خواهید کرد باید دارای فرمت .zip
باشد و دارای ساختار زیر باشد:
موفق باشید 🌟
فایل پروژه را میتوانید از طریق این این لینک دانلود کنید.
ساختار پروژه به شکل زیر است:
app.js
🔗Validation
و در پایین آن تابعی با نام isAuthentication
وجود دارد که شما باید آن را طوری کامل کنید که بررسی کند کاربر احراز هویت (authentication) را انجام داده است یا خیر.
پس باید مقداری را بر اساس مقادیر موجود در لوکالاستورج به ما برگرداند.registerUser
:🔗user
است که باید دارای سه مقدار باشد: username
، password
و role
.username
را پاکسازی و استاندارد میکنیم تا مقایسهای دقیق و یکسان برای بررسی تکراری بودن انجام شود.localStorage
خوانده میشود و در آرایهای به نام users
قرار میگیرد. اگر مقدار موجود در localStorage
آرایه نبود یا خطایی رخ داد، آرایه خالی در نظر گرفته میشود.username
(پس از پاکسازی) قبلاً ثبت شده یا خیر. اگر چنین کاربری وجود داشت، عملیات با پیام زیر رد میشود:
"این نام کاربری قبلاً ثبت شده. لطفاً نام دیگری انتخاب کنید."username
، password
و role
) به آرایه users
اضافه میشود.localStorage
ذخیره میشود. در صورتی که عملیات ذخیرهسازی با خطا مواجه شود، تابع با پیام زیر رد میشود:"خطا در ذخیرهسازی. دوباره تلاش کنید."
loginUser
🔗creds
است که شامل مقادیر username
و password
از loginForm
میباشد.accessToken
، refreshToken
و role
را بازمیگرداند. این مقادیر باید در localStorage
ذخیره شوند.registerUser
)، در ابتدا باید username
را پالایش کنید (حذف فاصلهها و تبدیل به حروف کوچک). سپس لیست کاربران (users
) از localStorage
خوانده میشود. در صورت بروز خطا یا نبود لیست معتبر، یک آرایه خالی جایگزین میشود.username
برابر و password
منطبق وجود دارد یا خیر. اگر چنین کاربری یافت نشد، reject
با پیام زیر صدا زده میشود و تابع خاتمه مییابد:
"نام کاربری یا رمز عبور اشتباه است."accessToken
و refreshToken
را با این فرمت تولید کنید:role
کاربر، در localStorage
ذخیره میشوند.try/catch
انجام شود. در صورت بروز خطا هنگام ذخیرهسازی، تابع با reject
و پیام زیر خاتمه مییابد:
"خطا در فرآیند ورود. دوباره تلاش کنید."resolve
فراخوانی میشود و آبجکت زیر بازگردانده میشود:loginUsername
) و رمز عبور (loginPassword
) از عناصر HTML دریافت میشوند.showToast
نمایش داده شده و ادامهی اجرای تابع متوقف میشود.username
و password
ساخته شده و به تابع loginUser
ارسال میشود.showToast
نمایش داده میشود و پس از گذشت یک ثانیه کاربر به صفحهی dashboard.html
هدایت میشود.showToast(err, "error")
نمایش داده میشود.فرایند ثبتنام بسیار مشابه ورود است با تفاوتهایی جزئی:
registerUsername
)، رمز عبور (registerPassword
) و نقش (role
) از عناصر HTML گرفته میشوند.username
، password
و role
ساخته میشود و به تابع registerUser
ارسال میگردد.login.html
منتقل میشود.showToast(err, "error")
نمایش داده خواهد شد.accessToken
، refreshToken
و role
از localStorage
خوانده میشوند.index.html
) هدایت شود.role
، محتوای مناسب برای داشبورد انتخاب و در عنصر dashboard-content
نمایش داده میشود:admin
باشد، محتوای مدیریتی (adminContent
) نمایش داده میشود.userContent
) قرار داده خواهد شد.logout-btn
پیدا میشود. در صورتی که وجود داشته باشد، یک رویداد کلیک برای آن تعریف میشود که هنگام کلیک:accessToken
، refreshToken
و role
را از localStorage
حذف میکند.index.html
) بازمیگرداند.برای هدایت صحیح کاربر به صفحات مجاز، بر اساس مسیر فعلی و وضعیت احراز هویت، شرایط زیر بررسی میشود:
dashboard.html
باشد ولی احراز هویت نشده باشد، باید به صفحهی login.html
منتقل شود.login.html
یا register.html
باشد ولی قبلاً احراز هویت شده باشد، باید مستقیماً به صفحهی dashboard.html
منتقل شود.index.html
یا ریشه /
) باشد:login.html
) منتقل میشود.هدف از این کنترلها، جلوگیری از دسترسی غیرمجاز به بخشهای محافظتشدهی سایت و همچنین جلوگیری از ورود کاربران لاگینشده به صفحات ورود و ثبتنام است. این کار تجربهی کاربری را بهبود میدهد و ساختار امنیتی سمت کلاینت را تقویت میکند.
app.js
متصل هستند.فایلی که آپلود خواهید کرد باید دارای فرمت .Zip باشد و دارای ساختار زیر باشد:
موفق باشید 🌟