├── Assignment 1 - Smart Grade
├── .eslintrc.cjs
├── .gitignore
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│ └── images
│ │ ├── 11.png
│ │ ├── 110.png
│ │ ├── 12.png
│ │ ├── 13.png
│ │ ├── 14.png
│ │ ├── 15.png
│ │ ├── 16.png
│ │ ├── 17.png
│ │ ├── 18.png
│ │ ├── 19.png
│ │ ├── 21.png
│ │ ├── 210.png
│ │ ├── 22.png
│ │ ├── 23.png
│ │ ├── 24.png
│ │ ├── 25.png
│ │ ├── 26.png
│ │ ├── 27.png
│ │ ├── 28.png
│ │ ├── 29.png
│ │ ├── 31.png
│ │ ├── 310.png
│ │ ├── 32.png
│ │ ├── 33.png
│ │ ├── 34.png
│ │ ├── 35.png
│ │ ├── 36.png
│ │ ├── 37.png
│ │ ├── 38.png
│ │ ├── 39.png
│ │ ├── avatar.png
│ │ ├── hero-graphics.svg
│ │ └── lws-logo-en.svg
├── src
│ ├── App.jsx
│ ├── assets
│ │ └── db
│ │ │ ├── class1.json
│ │ │ ├── class2.json
│ │ │ └── class3.json
│ ├── components
│ │ ├── Footer.jsx
│ │ ├── Header.jsx
│ │ ├── Hero.jsx
│ │ └── StudentTable.jsx
│ ├── index.css
│ └── main.jsx
├── tailwind.config.js
└── vite.config.js
├── Assignment 10 - LWS Kart
├── .env
├── .eslintrc.json
├── .gitignore
├── components.json
├── next.config.mjs
├── package-lock.json
├── package.json
├── postcss.config.mjs
├── public
│ ├── bd.png
│ ├── cron.png
│ ├── images
│ │ ├── admin-panel-2.jpg
│ │ ├── admin-panel-3.jpg
│ │ ├── admin-panel.jpg
│ │ ├── avatar.png
│ │ ├── category
│ │ │ ├── category-1.jpg
│ │ │ ├── category-2.jpg
│ │ │ ├── category-3.jpg
│ │ │ ├── category-4.jpg
│ │ │ ├── category-5.jpg
│ │ │ └── category-6.jpg
│ │ ├── complete.png
│ │ ├── favicon
│ │ │ ├── about.txt
│ │ │ ├── android-chrome-192x192.png
│ │ │ ├── android-chrome-512x512.png
│ │ │ ├── apple-touch-icon.png
│ │ │ ├── favicon-16x16.png
│ │ │ ├── favicon-32x32.png
│ │ │ ├── favicon.ico
│ │ │ └── site.webmanifest
│ │ ├── icons
│ │ │ ├── bed-2.svg
│ │ │ ├── bed.svg
│ │ │ ├── delivery-van.svg
│ │ │ ├── money-back.svg
│ │ │ ├── office.svg
│ │ │ ├── outdoor-cafe.svg
│ │ │ ├── phone.svg
│ │ │ ├── restaurant.svg
│ │ │ ├── service-hours.svg
│ │ │ ├── sofa.svg
│ │ │ └── terrace.svg
│ │ ├── logo-white.svg
│ │ ├── logo.svg
│ │ ├── methods.png
│ │ ├── offer.jpg
│ │ └── products
│ │ │ ├── product1.jpg
│ │ │ ├── product10.jpg
│ │ │ ├── product11.jpg
│ │ │ ├── product12.jpg
│ │ │ ├── product2.jpg
│ │ │ ├── product3.jpg
│ │ │ ├── product4.jpg
│ │ │ ├── product5.jpg
│ │ │ ├── product6.jpg
│ │ │ ├── product7.jpg
│ │ │ ├── product8.jpg
│ │ │ └── product9.jpg
│ ├── lws-logo.png
│ ├── next.svg
│ ├── resend_email_demo
│ │ └── email demo.png
│ ├── us.png
│ └── vercel.svg
├── src
│ ├── app
│ │ ├── [lang]
│ │ │ ├── (admin)
│ │ │ │ └── admin-dashboard
│ │ │ │ │ ├── error.tsx
│ │ │ │ │ ├── loading.tsx
│ │ │ │ │ ├── not-found.tsx
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ ├── priceChart
│ │ │ │ │ └── page.tsx
│ │ │ │ │ └── productList
│ │ │ │ │ └── page.tsx
│ │ │ ├── (user)
│ │ │ │ ├── about
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── account
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── banned
│ │ │ │ │ └── [userId]
│ │ │ │ │ │ └── page.tsx
│ │ │ │ ├── checkout
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── product-details
│ │ │ │ │ └── [id]
│ │ │ │ │ │ └── page.tsx
│ │ │ │ ├── shop
│ │ │ │ │ ├── loading.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ └── wishlist
│ │ │ │ │ ├── loading.tsx
│ │ │ │ │ └── page.tsx
│ │ │ ├── dictionaries.ts
│ │ │ ├── dictionaries
│ │ │ │ ├── bn.json
│ │ │ │ └── en.json
│ │ │ ├── error.tsx
│ │ │ ├── forgot-password
│ │ │ │ └── page.tsx
│ │ │ ├── globals.css
│ │ │ ├── interfaces.d.ts
│ │ │ ├── layout.tsx
│ │ │ ├── loading.tsx
│ │ │ ├── login
│ │ │ │ └── page.tsx
│ │ │ ├── new-password
│ │ │ │ └── page.tsx
│ │ │ ├── page.tsx
│ │ │ ├── register
│ │ │ │ └── page.tsx
│ │ │ └── sitemap.ts
│ │ ├── actions
│ │ │ ├── admin.actions.ts
│ │ │ ├── auth.actions.ts
│ │ │ ├── cart.actions.ts
│ │ │ ├── email.actions.ts
│ │ │ ├── order.actions.ts
│ │ │ ├── profile.actions.ts
│ │ │ ├── wishlist.actions.ts
│ │ │ └── zodSchema.index.ts
│ │ ├── api
│ │ │ ├── [...nextauth]
│ │ │ │ └── route.ts
│ │ │ ├── cart
│ │ │ │ ├── [id]
│ │ │ │ │ └── route.ts
│ │ │ │ └── route.ts
│ │ │ ├── profile
│ │ │ │ └── address
│ │ │ │ │ └── route.ts
│ │ │ ├── register
│ │ │ │ └── route.ts
│ │ │ ├── releaseProduct
│ │ │ │ └── route.ts
│ │ │ ├── reviews
│ │ │ │ └── [id]
│ │ │ │ │ └── route.ts
│ │ │ ├── search
│ │ │ │ ├── [query]
│ │ │ │ │ └── route.ts
│ │ │ │ └── count
│ │ │ │ │ └── [query]
│ │ │ │ │ └── route.ts
│ │ │ ├── stock
│ │ │ │ └── [id]
│ │ │ │ │ └── route.ts
│ │ │ ├── uploadthing
│ │ │ │ ├── core.ts
│ │ │ │ └── route.ts
│ │ │ ├── user
│ │ │ │ └── [email]
│ │ │ │ │ └── route.ts
│ │ │ └── wishlist
│ │ │ │ ├── [id]
│ │ │ │ └── route.ts
│ │ │ │ ├── count
│ │ │ │ └── [id]
│ │ │ │ │ └── route.ts
│ │ │ │ └── route.ts
│ │ ├── favicon.ico
│ │ ├── layout.tsx
│ │ ├── models
│ │ │ ├── TokenModel.ts
│ │ │ ├── ordersModel.ts
│ │ │ ├── passwordResetTokenModel.ts
│ │ │ ├── productModel.ts
│ │ │ └── userModel.ts
│ │ └── not-found.tsx
│ ├── assets
│ │ ├── banner-bg-1.jpg
│ │ ├── banner-bg-2.jpg
│ │ ├── banner-bg.jpg
│ │ └── container-img.jpg
│ ├── auth.ts
│ ├── components
│ │ ├── account
│ │ │ ├── AccountInfo.tsx
│ │ │ ├── AccountWrapper.tsx
│ │ │ ├── BillingAddress.tsx
│ │ │ ├── BillingForm.tsx
│ │ │ ├── DownloadButton.tsx
│ │ │ ├── MyOrders.tsx
│ │ │ ├── OrderPagination.tsx
│ │ │ ├── OrdersList.tsx
│ │ │ ├── PersonalProfile.tsx
│ │ │ ├── PersonalProfileEdit.tsx
│ │ │ ├── ProfilePasswordTab.tsx
│ │ │ ├── ReviewProduct.tsx
│ │ │ ├── ShippingAddress.tsx
│ │ │ ├── ShippingForm.tsx
│ │ │ └── StarReview.tsx
│ │ ├── admin
│ │ │ ├── AddNewProduct.tsx
│ │ │ ├── AddProductForm.tsx
│ │ │ ├── AdminCarousel.tsx
│ │ │ ├── AdminSearch.tsx
│ │ │ ├── AllLoaded.tsx
│ │ │ ├── LinkButtons.tsx
│ │ │ ├── LoadMore.tsx
│ │ │ ├── PriceChart.tsx
│ │ │ ├── Product.Admin.tsx
│ │ │ ├── ProductCategory.Admin.tsx
│ │ │ ├── ProductDelete.tsx
│ │ │ ├── ProductList.tsx
│ │ │ ├── ProductName.tsx
│ │ │ └── ProductStock.Admin.tsx
│ │ ├── auth
│ │ │ ├── ForgotPasswordForm.tsx
│ │ │ ├── FormRow.tsx
│ │ │ ├── LoginForm.tsx
│ │ │ ├── NewPasswordForm.tsx
│ │ │ ├── RegisterForm.tsx
│ │ │ ├── SignIn.tsx
│ │ │ └── SignOut.tsx
│ │ ├── checkout
│ │ │ ├── CartItem.tsx
│ │ │ ├── CheckoutForm.tsx
│ │ │ ├── CheckoutSummary.tsx
│ │ │ ├── CheckoutWrapper.tsx
│ │ │ ├── EmptyCart.tsx
│ │ │ ├── FormRow.tsx
│ │ │ ├── InvoicePDF.tsx
│ │ │ ├── OrderCard.tsx
│ │ │ ├── OrderDetailsDialog.tsx
│ │ │ ├── QuantityButton.tsx
│ │ │ ├── T&C.tsx
│ │ │ ├── T&CBengali.tsx
│ │ │ └── T&CEnglish.tsx
│ │ ├── common
│ │ │ ├── Breadcrumb.tsx
│ │ │ ├── Copyright.tsx
│ │ │ ├── Dropdown.tsx
│ │ │ ├── Footer.tsx
│ │ │ ├── Header.tsx
│ │ │ ├── HeaderButtons.tsx
│ │ │ ├── HeaderContainer.tsx
│ │ │ ├── LanguageSwitcher.tsx
│ │ │ ├── Navbar.tsx
│ │ │ ├── ScrollProgress.tsx
│ │ │ ├── ScrollToTop.tsx
│ │ │ ├── Search.tsx
│ │ │ ├── SearchSuggestionItem.tsx
│ │ │ └── TypeAnimation.tsx
│ │ ├── home
│ │ │ ├── Ads.tsx
│ │ │ ├── Advertising.tsx
│ │ │ ├── Banner.tsx
│ │ │ ├── BannerCarousel.tsx
│ │ │ ├── BannerText.tsx
│ │ │ ├── Categories.tsx
│ │ │ ├── ContainerScrollSection.tsx
│ │ │ ├── FAQ.tsx
│ │ │ ├── Features.tsx
│ │ │ ├── MotionButton.tsx
│ │ │ ├── NewArrival.tsx
│ │ │ ├── NewArrivalProducts.tsx
│ │ │ ├── RandomAdvertiseText.tsx
│ │ │ ├── Testimonial.tsx
│ │ │ ├── TrendingProducts.tsx
│ │ │ └── Trendings.tsx
│ │ ├── index.ts
│ │ ├── product
│ │ │ ├── AddtoCartButton.tsx
│ │ │ ├── Product.tsx
│ │ │ ├── ProductCount.tsx
│ │ │ ├── ProductDescription.tsx
│ │ │ ├── ProductDetails.tsx
│ │ │ ├── ProductDetailsCartButton.tsx
│ │ │ ├── ProductImages.tsx
│ │ │ ├── ProductLimit.tsx
│ │ │ ├── ProductMagnifier.tsx
│ │ │ ├── ProductShareButtons.tsx
│ │ │ ├── ProductWishlistButton.tsx
│ │ │ ├── Quantity.tsx
│ │ │ ├── RelatedProducts.tsx
│ │ │ ├── ReviewsButton.tsx
│ │ │ └── WishlistButton.tsx
│ │ ├── shop
│ │ │ ├── AllProducts.tsx
│ │ │ ├── ColorSlider.tsx
│ │ │ ├── DrawerContents.tsx
│ │ │ ├── DrawerTrigger.tsx
│ │ │ ├── NoProductMessage.tsx
│ │ │ ├── NoProducts.tsx
│ │ │ ├── ProductSkeleton.tsx
│ │ │ ├── ProductSorter.tsx
│ │ │ ├── ProductWrapper.tsx
│ │ │ ├── Products.tsx
│ │ │ ├── ResetFilters.tsx
│ │ │ ├── ShopPagination.tsx
│ │ │ ├── ShopWrapper.tsx
│ │ │ ├── Sidebar.tsx
│ │ │ ├── SidebarCategories.tsx
│ │ │ ├── SidebarPriceSize.tsx
│ │ │ └── SidebarStockStatus.tsx
│ │ ├── ui
│ │ │ ├── Navlink.tsx
│ │ │ ├── accordion.tsx
│ │ │ ├── avatar.tsx
│ │ │ ├── background-gradient.tsx
│ │ │ ├── badge.tsx
│ │ │ ├── bar-poll.tsx
│ │ │ ├── breadcrumb.tsx
│ │ │ ├── bubble-text.tsx
│ │ │ ├── button.tsx
│ │ │ ├── card-stack.tsx
│ │ │ ├── card.tsx
│ │ │ ├── carousel.tsx
│ │ │ ├── checkbox.tsx
│ │ │ ├── chip-tabs.tsx
│ │ │ ├── container-scroll.tsx
│ │ │ ├── dialog.tsx
│ │ │ ├── drawer.tsx
│ │ │ ├── dropdown-menu.tsx
│ │ │ ├── form.tsx
│ │ │ ├── hover-card.tsx
│ │ │ ├── image-hover.tsx
│ │ │ ├── input.tsx
│ │ │ ├── label.tsx
│ │ │ ├── movingBorder.tsx
│ │ │ ├── pagination.tsx
│ │ │ ├── radio-group.tsx
│ │ │ ├── select.tsx
│ │ │ ├── slider-toggle.tsx
│ │ │ ├── slider.tsx
│ │ │ ├── spotlight-btn.tsx
│ │ │ ├── staggered-dropdown.tsx
│ │ │ ├── tabs.tsx
│ │ │ ├── textarea.tsx
│ │ │ ├── toast-action.tsx
│ │ │ ├── toast.tsx
│ │ │ ├── toaster.tsx
│ │ │ ├── tooltip.tsx
│ │ │ └── use-toast.ts
│ │ └── wishlist
│ │ │ ├── AddToCartHoverMenu.tsx
│ │ │ ├── NoWishlist.tsx
│ │ │ ├── StockCount.tsx
│ │ │ ├── Wishlist.tsx
│ │ │ ├── WishlistItem.tsx
│ │ │ └── WishlistWrapper.tsx
│ ├── context
│ │ └── index.ts
│ ├── db
│ │ ├── connectMongo.ts
│ │ └── queries
│ │ │ ├── product.queries.ts
│ │ │ ├── token.queries.ts
│ │ │ └── user.queries.ts
│ ├── hooks
│ │ ├── admin-hooks
│ │ │ ├── useAdminProductCategory.ts
│ │ │ ├── useAdminProductDelete.ts
│ │ │ ├── useAdminProductForm.ts
│ │ │ └── useAdminProductStock.ts
│ │ ├── auth-hooks
│ │ │ ├── useLogin.ts
│ │ │ └── useRegister.ts
│ │ ├── cart-hooks
│ │ │ ├── useAddToCart.tsx
│ │ │ ├── useAddToCartHoverMenu.ts
│ │ │ ├── useCheckoutQuantityButton.ts
│ │ │ └── useCheckoutSummary.tsx
│ │ ├── context-hooks
│ │ │ ├── useCartContext.ts
│ │ │ ├── useFilterContext.ts
│ │ │ └── useWishlistContext.ts
│ │ ├── misc-hooks
│ │ │ ├── useDebounce.ts
│ │ │ ├── useMenuAnimation.ts
│ │ │ └── useStickyHeader.ts
│ │ ├── product-hooks
│ │ │ ├── useGetProducts.ts
│ │ │ ├── useGetSingleProduct.ts
│ │ │ ├── useMoveOfflineProductsToDB.ts
│ │ │ ├── usePagination.ts
│ │ │ ├── useQuantity.ts
│ │ │ ├── useReviewProduct.ts
│ │ │ ├── useSearch.ts
│ │ │ ├── useSearchSuggestion.ts
│ │ │ ├── useSidebarFilter.ts
│ │ │ ├── useStock.ts
│ │ │ └── useUseEffectMadness.ts
│ │ ├── profile-hooks
│ │ │ ├── useBillingForm.ts
│ │ │ ├── useForgotPassword.ts
│ │ │ ├── usePersonalProfileEdit.ts
│ │ │ ├── useShippingForm.ts
│ │ │ └── useUpdateProfileAddress.ts
│ │ └── wishlist-hooks
│ │ │ ├── useAddToWishlist.tsx
│ │ │ ├── useGetUserWishlist.ts
│ │ │ └── useWishlist.ts
│ ├── lib
│ │ └── utils.ts
│ ├── middleware.ts
│ ├── providers
│ │ ├── CartProvider.tsx
│ │ ├── CheckoutProvider.tsx
│ │ ├── FilterProvider.tsx
│ │ ├── QueryProvider.tsx
│ │ ├── ThemeProvider.tsx
│ │ ├── ToastProvider.tsx
│ │ └── WishlistProvider.tsx
│ └── utils
│ │ ├── barPollUtil.ts
│ │ ├── checkIfUserExists.ts
│ │ ├── constants.ts
│ │ ├── constructFilterPipeline.ts
│ │ ├── convertNumsToBengali.ts
│ │ ├── createImgBlur.ts
│ │ ├── createSearchParamsObjectForProducts.ts
│ │ ├── generateAuthToken.ts
│ │ ├── generatePasswordResetToken.ts
│ │ ├── getAvgReviewStars.tsx
│ │ ├── getCategoryIcons.tsx
│ │ ├── getFocusedFieldIcons.tsx
│ │ ├── getInitialReviewTab.ts
│ │ ├── getProductDiscountPercentage.ts
│ │ ├── getRandomNumber.ts
│ │ ├── getReviewStars.tsx
│ │ ├── getRndInt.ts
│ │ ├── getSuspenseKey.ts
│ │ ├── getUniqueCategories.ts
│ │ ├── headerFetchUtil.ts
│ │ ├── makeHTMLEmail.ts
│ │ ├── mongoClientPromise.ts
│ │ ├── redirectIfNotLoggedIn.ts
│ │ ├── revokeAdminIsUsersPages.ts
│ │ ├── revokeUserInAdminPanel.ts
│ │ ├── splitString.ts
│ │ ├── uploadthing.ts
│ │ ├── validateBDPhoneNumber.ts
│ │ └── validateEmail.ts
├── tailwind.config.ts
└── tsconfig.json
├── Assignment 2 - Book Finder
├── .eslintrc.cjs
├── .gitignore
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│ └── vite.svg
├── src
│ ├── App.jsx
│ ├── assets
│ │ ├── booksImages
│ │ │ ├── cracking_the_coding_interview.jpg
│ │ │ ├── eloquent_js.jpg
│ │ │ ├── hands_on_r_programming.jpg
│ │ │ ├── html_n_css.jpg
│ │ │ ├── js_jquery.png
│ │ │ ├── js_the_good_parts.jpg
│ │ │ ├── learn_js_quicky.jpg
│ │ │ ├── learning_js_design_patterns.jpg
│ │ │ ├── nodejs_design_pattern.jpg
│ │ │ ├── python_crash_course.jpg
│ │ │ ├── react_key_concept.jpg
│ │ │ ├── the_js_definitive_guide.jpg
│ │ │ ├── the_road_to_react.jpg
│ │ │ └── think_like_a_programmer.jpg
│ │ ├── logo.png
│ │ ├── lws-logo-en.svg
│ │ └── star.svg
│ ├── components
│ │ ├── Books
│ │ │ ├── BookGrid.jsx
│ │ │ └── BookGridItems.jsx
│ │ ├── Footer.jsx
│ │ ├── Header
│ │ │ ├── Header.jsx
│ │ │ ├── SearchBook.jsx
│ │ │ └── SortBy.jsx
│ │ ├── Layout.jsx
│ │ └── Navbar.jsx
│ ├── db
│ │ └── booksData.js
│ ├── index.css
│ └── main.jsx
├── tailwind.config.js
└── vite.config.js
├── Assignment 3 - Improve Tasker
├── .eslintrc.cjs
├── .gitignore
├── index.html
├── package.json
├── postcss.config.js
├── src
│ ├── App.jsx
│ ├── assets
│ │ ├── empty.svg
│ │ ├── frame.png
│ │ └── lws-logo-en.svg
│ ├── components
│ │ ├── Footer.jsx
│ │ ├── Header.jsx
│ │ ├── Hero.jsx
│ │ └── Tasks
│ │ │ ├── ActionModal.jsx
│ │ │ ├── Task.jsx
│ │ │ ├── TaskAction.jsx
│ │ │ ├── TaskContainer.jsx
│ │ │ ├── TaskHeader.jsx
│ │ │ ├── TaskSearch.jsx
│ │ │ └── Tasks.jsx
│ ├── contexts
│ │ └── TaskProvider.jsx
│ ├── database
│ │ └── data.js
│ ├── index.css
│ ├── main.jsx
│ ├── reducer
│ │ ├── actions.js
│ │ └── taskReducer.js
│ ├── ui
│ │ ├── Button.jsx
│ │ ├── DeleteModal.jsx
│ │ ├── NotFound.jsx
│ │ └── Tag.jsx
│ └── utils
│ │ ├── generateColor.js
│ │ └── generateId.js
├── tailwind.config.js
├── template
│ ├── add-task.html
│ ├── assets
│ │ ├── frame.png
│ │ └── lws-logo-en.svg
│ ├── index.html
│ └── styles
│ │ └── output.css
├── vite.config.js
└── yarn.lock
├── Assignment 4 - News Feeder
├── .env
├── .eslintrc.cjs
├── .gitignore
├── api
│ ├── README.md
│ ├── controller
│ │ └── news.controller.js
│ ├── data
│ │ └── news.json
│ ├── main.js
│ ├── package-lock.json
│ └── package.json
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│ └── vite.svg
├── src
│ ├── App.jsx
│ ├── Page.jsx
│ ├── assets
│ │ ├── fonts
│ │ │ ├── publico-headline-web
│ │ │ │ └── Publico-Headline-Web-Bold.ttf
│ │ │ └── tt-commons
│ │ │ │ ├── TTCommonsRegular.otf
│ │ │ │ └── TTCommonsSemiBold.otf
│ │ ├── icons
│ │ │ └── search.svg
│ │ ├── logo.png
│ │ ├── logo_light.png
│ │ ├── thumb.png
│ │ └── thumb_lg.png
│ ├── components
│ │ ├── Footer.jsx
│ │ ├── FooterBottom.jsx
│ │ ├── Navbar
│ │ │ ├── Categories.jsx
│ │ │ ├── NavDate.jsx
│ │ │ ├── Navbar.jsx
│ │ │ ├── SVG.jsx
│ │ │ └── Search.jsx
│ │ ├── News
│ │ │ ├── EmptyResponse.jsx
│ │ │ ├── Error.jsx
│ │ │ ├── Info.jsx
│ │ │ ├── LeftNews.jsx
│ │ │ ├── Loader.jsx
│ │ │ ├── NewsContainer.jsx
│ │ │ ├── NewsItem.jsx
│ │ │ ├── RightNews.jsx
│ │ │ └── Thumbnail.jsx
│ │ ├── NewsLetter.jsx
│ │ └── SocialIcons.jsx
│ ├── constants
│ │ └── constant.js
│ ├── context
│ │ └── index.js
│ ├── hooks
│ │ ├── useDebounce.js
│ │ ├── useNewsQuery.js
│ │ └── useSearch.js
│ ├── index.css
│ ├── main.jsx
│ ├── provider
│ │ ├── NewsProvider.jsx
│ │ ├── SearchProvider.jsx
│ │ ├── ThemeProvider.jsx
│ │ └── index.js
│ └── utils
│ │ ├── formatDate.js
│ │ └── getCurrentDate.js
├── tailwind.config.js
└── vite.config.js
├── Assignment 5 - React Blogify
├── .env
├── .eslintrc.cjs
├── .gitignore
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│ └── vite.svg
├── src
│ ├── App.jsx
│ ├── assets
│ │ ├── avatar.png
│ │ ├── blogs
│ │ │ ├── React-Roadmap.jpg
│ │ │ ├── Underrated Video.jpg
│ │ │ └── taiulwind-cn-thumb.jpg
│ │ ├── fonts
│ │ │ ├── Europa-Bold.woff
│ │ │ ├── Europa-Bold.woff2
│ │ │ ├── Europa-Regular.woff
│ │ │ └── Europa-Regular.woff2
│ │ ├── icons
│ │ │ ├── 3dots.svg
│ │ │ ├── close.svg
│ │ │ ├── comment.svg
│ │ │ ├── delete.svg
│ │ │ ├── edit.svg
│ │ │ ├── heart-filled.svg
│ │ │ ├── heart.svg
│ │ │ ├── like.svg
│ │ │ └── search.svg
│ │ ├── image.avif
│ │ ├── logo.svg
│ │ ├── picture.svg
│ │ ├── play.svg
│ │ └── share.svg
│ ├── components
│ │ ├── Profile
│ │ │ ├── ActionButton.jsx
│ │ │ ├── ProfileInfo.jsx
│ │ │ └── ProfileSkeleton.jsx
│ │ ├── Search
│ │ │ └── Search.jsx
│ │ ├── SingleBlog
│ │ │ ├── Comment.jsx
│ │ │ ├── CommentSection.jsx
│ │ │ ├── DeleteModal.jsx
│ │ │ ├── FloatingMenu.jsx
│ │ │ └── TopDetails.jsx
│ │ ├── auth
│ │ │ └── FormRow.jsx
│ │ ├── common
│ │ │ ├── Avatar.jsx
│ │ │ ├── EmptyResponse.jsx
│ │ │ ├── Error.jsx
│ │ │ ├── Footer.jsx
│ │ │ ├── Header.jsx
│ │ │ ├── ScrollToTopOnRouteChange.jsx
│ │ │ └── Tooltip.jsx
│ │ ├── homepage
│ │ │ ├── BlogCard.jsx
│ │ │ ├── BlogContainer.jsx
│ │ │ ├── BlogContent.jsx
│ │ │ ├── BlogSidebar.jsx
│ │ │ ├── BlogSkeleton.jsx
│ │ │ ├── FavoriteBlogs.jsx
│ │ │ ├── PopularBlogs.jsx
│ │ │ └── PopularSkeleton.jsx
│ │ └── misc
│ │ │ ├── LikeSVG.jsx
│ │ │ ├── Loader.jsx
│ │ │ ├── ScrollProgress.jsx
│ │ │ └── ScrollToTop.jsx
│ ├── constants.js
│ ├── context
│ │ └── index.js
│ ├── hooks
│ │ ├── api
│ │ │ ├── useAxios.js
│ │ │ ├── useClearAllFav.js
│ │ │ ├── useComment.js
│ │ │ ├── useCreateBlog.js
│ │ │ ├── useDeleteBlog.js
│ │ │ ├── useEditBlog.js
│ │ │ ├── useFavorite.js
│ │ │ ├── useGetLikedUsers.js
│ │ │ ├── useGetPopular.js
│ │ │ ├── useGetSingleBlog.js
│ │ │ ├── useGetUser.js
│ │ │ ├── useLikeBlog.js
│ │ │ ├── useLoginUser.js
│ │ │ ├── useRefreshToken.js
│ │ │ ├── useRegisterUser.js
│ │ │ ├── useReorderBlog.js
│ │ │ ├── useSearch.js
│ │ │ └── useUpdateProfile.js
│ │ ├── useAuth.js
│ │ ├── useDebounce.js
│ │ └── usePortal.js
│ ├── index.css
│ ├── main.jsx
│ ├── pages
│ │ ├── Blog.jsx
│ │ ├── EditBlog.jsx
│ │ ├── Error.jsx
│ │ ├── PrivateRoute.jsx
│ │ ├── Profile.jsx
│ │ ├── SingleBlog.jsx
│ │ ├── WriteBlog.jsx
│ │ └── auth
│ │ │ ├── AlreadyLoggedIn.jsx
│ │ │ ├── Login.jsx
│ │ │ └── Register.jsx
│ ├── providers
│ │ ├── AuthProvider.jsx
│ │ ├── FavoriteProvider.jsx
│ │ └── SearchProvider.jsx
│ ├── reducer
│ │ └── blogReducer.js
│ └── utils
│ │ ├── customFetch.js
│ │ ├── formatDate.js
│ │ ├── generateFullName.js
│ │ ├── getBlogs.js
│ │ ├── getLikeCountString.js
│ │ ├── handleOutsideClick.js
│ │ └── uploadImage.js
├── tailwind.config.js
├── todo.md
├── vercel.json
└── vite.config.js
├── Assignment 6 - Shop Center
├── .eslintrc.json
├── .gitignore
├── Data
│ ├── database.js
│ └── index.js
├── app
│ ├── (withFooter)
│ │ ├── categories
│ │ │ ├── [category]
│ │ │ │ └── page.js
│ │ │ ├── layout.js
│ │ │ └── page.js
│ │ ├── layout.js
│ │ └── page.js
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.js
│ └── products
│ │ └── [id]
│ │ └── page.jsx
├── assets
│ ├── header.webp
│ ├── lws-logo-black.svg
│ ├── product-1.webp
│ ├── product-1s.webp
│ ├── product-2.webp
│ ├── product-3-hover.webp
│ ├── product-3.webp
│ ├── product-4.webp
│ ├── product-5-front.webp
│ ├── product-5.webp
│ ├── products
│ │ ├── iphone-2.jpg
│ │ ├── iphone-3.jpg
│ │ ├── iphone-4.jpg
│ │ ├── iphone.jpg
│ │ ├── macbook-pro.png
│ │ ├── perfume.jpg
│ │ └── samsung-galaxy-book.jpg
│ └── svg
│ │ ├── avatar.svg
│ │ ├── menu.svg
│ │ ├── plus.svg
│ │ ├── search.svg
│ │ ├── shopping-Cart.svg
│ │ ├── star.svg
│ │ └── tick.svg
├── components
│ ├── Home
│ │ └── Hero.jsx
│ ├── NavLink.jsx
│ ├── Navbar.jsx
│ ├── Product
│ │ └── ProductImages.jsx
│ ├── ProductComp.jsx
│ └── ProductList.jsx
├── jsconfig.json
├── next.config.mjs
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│ ├── next.svg
│ └── vercel.svg
├── tailwind.config.js
└── utils
│ └── minusPercentage.js
├── Assignment 7 - Movie DB
├── .eslintrc.json
├── .gitignore
├── app
│ ├── [lang]
│ │ ├── @home
│ │ │ ├── default.jsx
│ │ │ └── page.jsx
│ │ ├── @movie
│ │ │ ├── (.)movies
│ │ │ │ └── [movieId]
│ │ │ │ │ └── page.jsx
│ │ │ └── default.jsx
│ │ ├── _dictionaries
│ │ │ ├── bn.json
│ │ │ ├── dictionaries.js
│ │ │ └── en.json
│ │ ├── layout.jsx
│ │ ├── movies
│ │ │ └── [movieId]
│ │ │ │ ├── not-found.jsx
│ │ │ │ └── page.jsx
│ │ └── page.jsx
│ ├── _components
│ │ ├── Footer.jsx
│ │ ├── Header.jsx
│ │ ├── LanguageSwitcher.jsx
│ │ ├── Modal.jsx
│ │ ├── Sidebar.jsx
│ │ ├── ThemeSwitcher.jsx
│ │ └── home
│ │ │ └── MovieCard.jsx
│ ├── api
│ │ ├── movie
│ │ │ └── [id]
│ │ │ │ └── route.js
│ │ └── movies
│ │ │ └── route.js
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.jsx
│ └── not-found.jsx
├── data
│ ├── data.json
│ └── genres.json
├── jsconfig.json
├── middleware.js
├── next.config.mjs
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│ ├── assets
│ │ ├── bd.png
│ │ ├── cart-item.png
│ │ ├── delete.svg
│ │ ├── gear.svg
│ │ ├── icons
│ │ │ ├── checkout.svg
│ │ │ ├── commingSoon.svg
│ │ │ ├── favourite.svg
│ │ │ ├── moon.svg
│ │ │ ├── newRelease.svg
│ │ │ ├── sun.svg
│ │ │ ├── trending.svg
│ │ │ ├── watchLater.svg
│ │ │ └── xmark.svg
│ │ ├── logo.svg
│ │ ├── movie-1.png
│ │ ├── ring.svg
│ │ ├── shopping-cart.svg
│ │ ├── star.svg
│ │ ├── tag.svg
│ │ └── usa.png
│ ├── next.svg
│ └── vercel.svg
├── tailwind.config.js
└── utils
│ └── changeTheme.js
├── Assignment 8 - Khana Khazana
├── .env
├── .eslintrc.json
├── .gitignore
├── jsconfig.json
├── next.config.mjs
├── package-lock.json
├── package.json
├── postcss.config.mjs
├── public
│ ├── assets
│ │ └── images
│ │ │ ├── cover.png
│ │ │ └── logo.png
│ ├── next.svg
│ └── vercel.svg
├── src
│ ├── actions.js
│ ├── app
│ │ ├── error.jsx
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── layout.js
│ │ ├── loading.jsx
│ │ ├── login
│ │ │ └── page.jsx
│ │ ├── not-found.jsx
│ │ ├── page.js
│ │ ├── recipe-details
│ │ │ ├── [id]
│ │ │ │ └── page.jsx
│ │ │ └── error.jsx
│ │ ├── recipe
│ │ │ ├── [category]
│ │ │ │ └── page.jsx
│ │ │ └── error.jsx
│ │ ├── register
│ │ │ └── page.jsx
│ │ └── sitemap.js
│ ├── components
│ │ ├── Auth
│ │ │ ├── LoginForm.jsx
│ │ │ ├── RegisterForm.jsx
│ │ │ └── Submit.jsx
│ │ ├── Common
│ │ │ ├── LoggedIn.jsx
│ │ │ ├── ModifiableInput.jsx
│ │ │ ├── RecipeCard.jsx
│ │ │ └── RecipeCardGrid.jsx
│ │ ├── Details
│ │ │ ├── Food.jsx
│ │ │ ├── FoodButtons.jsx
│ │ │ └── RecipeSteps.jsx
│ │ ├── Home
│ │ │ ├── Hero.jsx
│ │ │ ├── Navbar.jsx
│ │ │ ├── RecipeContainer.jsx
│ │ │ └── RecipesList.jsx
│ │ ├── Icons
│ │ │ ├── CookTime.jsx
│ │ │ ├── Favourite.jsx
│ │ │ ├── Prep.jsx
│ │ │ ├── Servings.jsx
│ │ │ └── Share.jsx
│ │ └── Misc
│ │ │ └── Tooltip.jsx
│ ├── context
│ │ └── index.js
│ ├── db
│ │ ├── conectMongo.js
│ │ └── queries.js
│ ├── hooks
│ │ ├── useAuth.js
│ │ ├── useFavorite.js
│ │ ├── useFoodButtons.js
│ │ ├── useInputTypeConverter.js
│ │ └── useMenuAnimation.js
│ ├── middleware.js
│ ├── models
│ │ ├── Recipe.js
│ │ └── User.js
│ ├── provider
│ │ ├── AuthProvider.jsx
│ │ └── FavoriteProvider.jsx
│ └── util
│ │ ├── checkValidMongooseId.js
│ │ ├── constants.js
│ │ ├── getRandomInteger.js
│ │ ├── getUniqueCategories.js
│ │ └── validateInput.js
├── tailwind.config.js
└── todo.md
└── README.md
/Assignment 1 - Smart Grade/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react-refresh/only-export-components': [
16 | 'warn',
17 | { allowConstantExport: true },
18 | ],
19 | },
20 | }
21 |
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | SmartGrade Showcase | Learn with Sumit
8 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/11.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/110.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/110.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/12.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/13.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/14.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/15.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/16.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/17.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/18.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/19.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/21.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/210.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/210.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/22.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/23.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/24.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/25.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/26.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/26.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/27.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/28.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/28.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/29.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/31.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/31.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/310.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/32.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/33.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/33.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/34.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/34.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/35.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/35.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/36.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/37.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/38.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/39.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/39.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/public/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 1 - Smart Grade/public/images/avatar.png
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/src/App.jsx:
--------------------------------------------------------------------------------
1 | import Footer from "./components/Footer";
2 | import Header from "./components/Header";
3 | import Hero from "./components/Hero";
4 | import StudentTable from "./components/StudentTable";
5 |
6 | export default function App() {
7 | return (
8 | <>
9 |
10 |
11 |
12 |
13 |
14 |
15 | >
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/src/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | export default function Footer() {
2 | const date = new Date();
3 | return (
4 | <>
5 |
13 | >
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/src/components/Header.jsx:
--------------------------------------------------------------------------------
1 | import lws from "/images/lws-logo-en.svg";
2 |
3 | export default function Header() {
4 | return (
5 | <>
6 |
24 | >
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: ["./index.html", "./src/**/*.{js,jsx,ts,tsx}"],
4 | theme: {
5 | extend: {
6 | keyframes: {
7 | "animate-updown": {
8 | "0%, 100%": { transform: "translateY(-20px)" },
9 | "50%": { transform: "translateY(20px)" },
10 | },
11 | },
12 | },
13 | },
14 | plugins: [],
15 | };
16 |
--------------------------------------------------------------------------------
/Assignment 1 - Smart Grade/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | dist
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "src/app/globals.css",
9 | "baseColor": "slate",
10 | "cssVariables": false,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils"
16 | }
17 | }
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | images: {
4 | remotePatterns: [
5 | {
6 | protocol: 'https',
7 | hostname: 'lh3.googleusercontent.com',
8 | },
9 | {
10 | protocol: 'https',
11 | hostname: 'utfs.io',
12 | },
13 | {
14 | protocol: 'https',
15 | hostname: 'unsplash.com',
16 | },
17 | {
18 | protocol: 'https',
19 | hostname: '*.unsplash.com',
20 | },
21 | {
22 | protocol: 'https',
23 | hostname: 'platform-lookaside.fbsbx.com',
24 | },
25 | ],
26 | },
27 | }
28 |
29 | export default nextConfig
30 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/bd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/bd.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/cron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/cron.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/admin-panel-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/admin-panel-2.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/admin-panel-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/admin-panel-3.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/admin-panel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/admin-panel.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/avatar.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/category/category-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/category/category-1.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/category/category-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/category/category-2.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/category/category-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/category/category-3.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/category/category-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/category/category-4.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/category/category-5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/category/category-5.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/category/category-6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/category/category-6.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/complete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/complete.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/favicon/about.txt:
--------------------------------------------------------------------------------
1 | This favicon was generated using the following font:
2 |
3 | - Font Title: Roboto
4 | - Font Author: Copyright 2011 Google Inc. All Rights Reserved.
5 | - Font Source: http://fonts.gstatic.com/s/roboto/v29/KFOlCnqEu92Fr1MmWUlvAx05IsDqlA.ttf
6 | - Font License: Apache License, version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html))
7 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/favicon/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/favicon/android-chrome-192x192.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/favicon/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/favicon/android-chrome-512x512.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/favicon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/favicon/favicon-16x16.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/favicon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/favicon/favicon-32x32.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/favicon/favicon.ico
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/favicon/site.webmanifest:
--------------------------------------------------------------------------------
1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/methods.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/methods.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/offer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/offer.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product1.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product10.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product11.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product12.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product2.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product3.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product4.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product5.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product6.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product7.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product8.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/images/products/product9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/images/products/product9.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/lws-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/lws-logo.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/resend_email_demo/email demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/resend_email_demo/email demo.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/us.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/public/us.png
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/[lang]/(user)/about/page.tsx:
--------------------------------------------------------------------------------
1 | import { ContainerScrollSection } from '@/components/home/ContainerScrollSection'
2 | import { FAQAccordion } from '@/components/home/FAQ'
3 | import { Testimonial } from '@/components/home/Testimonial'
4 | import { Metadata } from 'next'
5 |
6 | export const metadata: Metadata = {
7 | title: 'About',
8 | description: 'LWS Kart About',
9 | }
10 |
11 | const AboutPage = () => {
12 | return (
13 |
14 |
15 |
16 |
17 |
18 | )
19 | }
20 |
21 | export default AboutPage
22 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/[lang]/(user)/wishlist/page.tsx:
--------------------------------------------------------------------------------
1 | import { Wishlist, WishlistWrapper } from '@/components'
2 | import ReactQueryProvider from '@/providers/QueryProvider'
3 | import redirectIfNotLoggedIn from '@/utils/redirectIfNotLoggedIn'
4 | import revokeAdminIsUsersPages from '@/utils/revokeAdminIsUsersPages'
5 | import { Metadata } from 'next'
6 |
7 | export const metadata: Metadata = {
8 | title: 'Wishlist',
9 | description: 'LWS Kart Wishlist',
10 | }
11 |
12 | const WishlistPage = async () => {
13 | await revokeAdminIsUsersPages()
14 | const userId = await redirectIfNotLoggedIn()
15 | return (
16 |
17 |
18 |
19 |
20 |
21 | )
22 | }
23 | export default WishlistPage
24 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/[lang]/dictionaries.ts:
--------------------------------------------------------------------------------
1 | import 'server-only'
2 |
3 | export type Locale = keyof typeof dictionaries
4 |
5 | const dictionaries = {
6 | en: () => import('./dictionaries/en.json').then((module) => module.default),
7 | bn: () => import('./dictionaries/bn.json').then((module) => module.default),
8 | }
9 |
10 | export const getDictionary = async (locale: Locale) =>
11 | locale === 'en' ? dictionaries.en() : dictionaries.bn()
12 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/[lang]/error.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | export default function Error({
4 | reset,
5 | }: {
6 | error: Error & { digest?: string }
7 | reset: () => void
8 | }) {
9 | return (
10 |
11 |
12 |
13 | Something Went Wrong!
14 |
15 |
16 | An unexpected error has occurred. Please try again later.
17 |
18 |
24 |
25 |
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/[lang]/forgot-password/page.tsx:
--------------------------------------------------------------------------------
1 | import { ForgotPasswordForm } from '../../../components/auth/ForgotPasswordForm'
2 | import { getDictionary } from '../dictionaries'
3 |
4 | const ForgotPassword = async ({
5 | params: { lang },
6 | }: {
7 | params: { lang: ILang['lang'] }
8 | }) => {
9 | const dictionary = await getDictionary(lang)
10 | return (
11 |
12 |
13 |
14 | )
15 | }
16 | export default ForgotPassword
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/[lang]/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | /* width */
6 | ::-webkit-scrollbar {
7 | width: 10px;
8 | }
9 |
10 | /* Track */
11 | ::-webkit-scrollbar-track {
12 | background: #f1f1f1;
13 | }
14 |
15 | /* Handle */
16 | ::-webkit-scrollbar-thumb {
17 | background: #0cd7d7;
18 | border-radius: 10px;
19 | }
20 |
21 | /* Handle on hover */
22 | ::-webkit-scrollbar-thumb:hover {
23 | background: #17bfbf;
24 | }
25 | /* stock-count.css */
26 | .stock-count::-webkit-outer-spin-button,
27 | .stock-count::-webkit-inner-spin-button {
28 | -webkit-appearance: none;
29 | margin: 0;
30 | }
31 |
32 | /* Firefox */
33 | .stock-count[type='number'] {
34 | -moz-appearance: textfield;
35 | }
36 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/[lang]/new-password/page.tsx:
--------------------------------------------------------------------------------
1 | import { NewPasswordForm } from '@/components/auth/NewPasswordForm'
2 | import { getDictionary } from '../dictionaries'
3 |
4 | const NewPasswordPage = async ({
5 | params: { lang },
6 | }: {
7 | params: { lang: ILang['lang'] }
8 | }) => {
9 | const dictionary = await getDictionary(lang)
10 | return (
11 |
12 |
13 |
14 | )
15 | }
16 | export default NewPasswordPage
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/[lang]/sitemap.ts:
--------------------------------------------------------------------------------
1 | import { getAllProducts } from '@/db/queries/product.queries'
2 |
3 | export default async function sitemap() {
4 | const products = await getAllProducts()
5 | const productEntitiesById = products.map(({ _id }) => ({
6 | url: `${process.env.BASE_URL}/product-details/${_id}`,
7 | }))
8 |
9 | return [
10 | {
11 | url: `${process.env.BASE_URL}`,
12 | },
13 | ...productEntitiesById,
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/actions/zodSchema.index.ts:
--------------------------------------------------------------------------------
1 | import { validateEmail } from '@/utils/validateEmail'
2 | import { z } from 'zod'
3 |
4 | export const ResetFormSchema = z.object({
5 | email: z
6 | .string()
7 | .refine((value) => validateEmail(value), { message: 'Invalid Email' }),
8 | recoveryEmail: z
9 | .string()
10 | .refine((value) => validateEmail(value), { message: 'Invalid Email' }),
11 | })
12 |
13 | export const loginFormSchema = z.object({
14 | email: z.string().refine((email) => validateEmail(email), {
15 | message: 'Invalid Email',
16 | }),
17 | password: z.string().min(1, { message: 'Password cannot be empty' }),
18 | remember: z.boolean(),
19 | })
20 |
21 | export const NewPasswordFormSchema = z.object({
22 | password: z
23 | .string()
24 | .min(6, { message: 'Password must be at least 6 characters' }),
25 | })
26 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/[...nextauth]/route.ts:
--------------------------------------------------------------------------------
1 | export { GET, POST } from '@/auth'
2 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/cart/[id]/route.ts:
--------------------------------------------------------------------------------
1 | import connectMongo from '@/db/connectMongo'
2 | import { getCurrentUserCart } from '@/db/queries/user.queries'
3 | import { NextRequest, NextResponse } from 'next/server'
4 |
5 | export const GET = async (
6 | _: NextRequest,
7 | { params: { id } }: { params: { id: string } }
8 | ) => {
9 | await connectMongo()
10 | try {
11 | const cart = await getCurrentUserCart(id)
12 | return NextResponse.json(cart, { status: 200 })
13 | } catch (error) {
14 | throw error
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/cart/route.ts:
--------------------------------------------------------------------------------
1 | import { addProductToCart } from '@/app/actions/cart.actions'
2 | import connectMongo from '@/db/connectMongo'
3 | import { NextRequest, NextResponse } from 'next/server'
4 |
5 | export const POST = async (request: NextRequest) => {
6 | await connectMongo()
7 | const { userId, product } = await request.json()
8 | try {
9 | const user = await addProductToCart(userId, product)
10 | return NextResponse.json(user, { status: 200 })
11 | } catch (error) {
12 | throw error
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/profile/address/route.ts:
--------------------------------------------------------------------------------
1 | import { updateProfileAddress } from '@/app/actions/profile.actions'
2 | import connectMongo from '@/db/connectMongo'
3 | import { NextRequest, NextResponse } from 'next/server'
4 |
5 | export const PATCH = async (request: NextRequest) => {
6 | await connectMongo()
7 | const { userId, update } = await request.json()
8 | try {
9 | const user = await updateProfileAddress(userId, update)
10 | return NextResponse.json(user, { status: 200 })
11 | } catch (error) {
12 | throw error
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/reviews/[id]/route.ts:
--------------------------------------------------------------------------------
1 | import connectMongo from '@/db/connectMongo'
2 | import { getSingleProduct } from '@/db/queries/product.queries'
3 | import { NextRequest, NextResponse } from 'next/server'
4 |
5 | export const GET = async (
6 | _: NextRequest,
7 | { params: { id } }: { params: { id: string } }
8 | ) => {
9 | await connectMongo()
10 | try {
11 | const reviews = await getSingleProduct(id, 'reviews')
12 | return NextResponse.json({ reviews }, { status: 200 })
13 | } catch (error) {
14 | throw error
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/search/[query]/route.ts:
--------------------------------------------------------------------------------
1 | import connectMongo from '@/db/connectMongo'
2 | import { getSearchedProducts } from '@/db/queries/product.queries'
3 | import { NextRequest, NextResponse } from 'next/server'
4 |
5 | export const GET = async (
6 | request: NextRequest,
7 | { params: { query } }: { params: { query: string } }
8 | ) => {
9 | const { searchParams } = new URL(request.url)
10 | const limit = searchParams.get('limit')
11 | await connectMongo()
12 | try {
13 | const products = await getSearchedProducts(query, Number(limit))
14 | return NextResponse.json({ products }, { status: 200 })
15 | } catch (error) {
16 | throw error
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/search/count/[query]/route.ts:
--------------------------------------------------------------------------------
1 | import connectMongo from '@/db/connectMongo'
2 | import { getTotalProductCount } from '@/db/queries/product.queries'
3 | import { NextRequest, NextResponse } from 'next/server'
4 |
5 | export const GET = async (
6 | _: NextRequest,
7 | { params: { query } }: { params: { query: string } }
8 | ) => {
9 | await connectMongo()
10 | try {
11 | const products = await getTotalProductCount(query)
12 | return NextResponse.json({ products }, { status: 200 })
13 | } catch (error) {
14 | throw error
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/stock/[id]/route.ts:
--------------------------------------------------------------------------------
1 | import connectMongo from '@/db/connectMongo'
2 | import { getSingleProduct } from '@/db/queries/product.queries'
3 | import { NextRequest, NextResponse } from 'next/server'
4 |
5 | export const GET = async (
6 | _: NextRequest,
7 | { params: { id } }: { params: { id: string } }
8 | ) => {
9 | await connectMongo()
10 | try {
11 | const product = await getSingleProduct(id)
12 | return NextResponse.json({ stock: product.stock_count }, { status: 200 })
13 | } catch (error) {
14 | throw error
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/uploadthing/route.ts:
--------------------------------------------------------------------------------
1 | import { createRouteHandler } from 'uploadthing/next'
2 |
3 | import { ourFileRouter } from './core'
4 |
5 | export const { GET, POST } = createRouteHandler({
6 | router: ourFileRouter,
7 | })
8 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/user/[email]/route.ts:
--------------------------------------------------------------------------------
1 | import connectMongo from '@/db/connectMongo'
2 | import { getUserByEmail } from '@/db/queries/user.queries'
3 | import { NextRequest, NextResponse } from 'next/server'
4 |
5 | export const GET = async (
6 | _: NextRequest,
7 | { params: { email } }: { params: { email: string } }
8 | ) => {
9 | await connectMongo()
10 | try {
11 | const { status } = await getUserByEmail(email)
12 | return NextResponse.json(status, { status: 200 })
13 | } catch (error) {
14 | throw error
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/wishlist/[id]/route.ts:
--------------------------------------------------------------------------------
1 | import connectMongo from '@/db/connectMongo'
2 | import { getCurrentUserWishlist } from '@/db/queries/user.queries'
3 | import { NextRequest, NextResponse } from 'next/server'
4 |
5 | export const GET = async (
6 | request: NextRequest,
7 | { params: { id } }: { params: { id: string } }
8 | ) => {
9 | const { searchParams } = new URL(request.url)
10 | const limit = searchParams.get('limit')
11 |
12 | await connectMongo()
13 | try {
14 | const wishlist = await getCurrentUserWishlist(id, Number(limit))
15 | return NextResponse.json(wishlist, { status: 200 })
16 | } catch (error) {
17 | throw error
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/wishlist/count/[id]/route.ts:
--------------------------------------------------------------------------------
1 | import connectMongo from '@/db/connectMongo'
2 | import { getWishlistCount } from '@/db/queries/user.queries'
3 | import { NextRequest, NextResponse } from 'next/server'
4 |
5 | export const GET = async (
6 | _: NextRequest,
7 | { params: { id } }: { params: { id: string } }
8 | ) => {
9 | await connectMongo()
10 | try {
11 | const wishlist = await getWishlistCount(id)
12 | return NextResponse.json(wishlist, { status: 200 })
13 | } catch (error) {
14 | throw error
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/api/wishlist/route.ts:
--------------------------------------------------------------------------------
1 | import { addProductToWishlist } from '@/app/actions/wishlist.actions'
2 | import connectMongo from '@/db/connectMongo'
3 | import { NextRequest, NextResponse } from 'next/server'
4 |
5 | export const POST = async (request: NextRequest) => {
6 | await connectMongo()
7 | const { userId, product } = await request.json()
8 | try {
9 | const user = await addProductToWishlist(userId, product)
10 | return NextResponse.json(user, { status: 200 })
11 | } catch (error) {
12 | throw error
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/src/app/favicon.ico
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from 'next'
2 | import { Poppins } from 'next/font/google'
3 | import './[lang]/globals.css'
4 | import { releaseProductsFromCartAndRestoreStock } from './actions/cart.actions'
5 |
6 | const poppins = Poppins({
7 | subsets: ['latin'],
8 | weight: ['100', '200', '300', '400', '500', '600', '700', '800', '900'],
9 | })
10 |
11 | export const metadata: Metadata = {
12 | title: 'LWS Kart',
13 | description: 'E-commerce Application of Learn with Sumit',
14 | }
15 |
16 | export default async function RootLayout({
17 | children,
18 | }: Readonly<{
19 | children: React.ReactNode
20 | }>) {
21 | return (
22 |
23 | {children}
24 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/models/TokenModel.ts:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose'
2 |
3 | const AuthTokenSchema = new mongoose.Schema({
4 | email: String,
5 | accessToken: {
6 | type: String,
7 | required: true,
8 | },
9 | aTExp: Date,
10 | refreshToken: {
11 | type: String,
12 | required: true,
13 | },
14 | rTExp: Date,
15 | })
16 |
17 | export const AuthTokenModel =
18 | mongoose.models.authTokens || mongoose.model('authTokens', AuthTokenSchema)
19 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/models/ordersModel.ts:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose'
2 | import { product } from './userModel'
3 |
4 | const OrderSchema = new mongoose.Schema({
5 | userId: {
6 | type: String,
7 | required: true,
8 | },
9 | userDetails: {
10 | firstName: String,
11 | lastName: String,
12 | region: String,
13 | address: String,
14 | city: String,
15 | phone: String,
16 | email: String,
17 | },
18 | items: [product],
19 | cost: {
20 | type: Number,
21 | required: true,
22 | },
23 | })
24 |
25 | export const OrdersModel =
26 | mongoose.models.orders || mongoose.model('orders', OrderSchema)
27 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/app/models/passwordResetTokenModel.ts:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose'
2 |
3 | const PasswordResetTokenSchema = new mongoose.Schema({
4 | email: String,
5 | token: {
6 | type: String,
7 | unique: true,
8 | },
9 | expires: Date,
10 | })
11 |
12 | export const PasswordResetTokenModel =
13 | mongoose.models.passwordResetToken ||
14 | mongoose.model('passwordResetToken', PasswordResetTokenSchema)
15 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/assets/banner-bg-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/src/assets/banner-bg-1.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/assets/banner-bg-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/src/assets/banner-bg-2.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/assets/banner-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/src/assets/banner-bg.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/assets/container-img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 10 - LWS Kart/src/assets/container-img.jpg
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/account/AccountWrapper.tsx:
--------------------------------------------------------------------------------
1 | const AccountWrapper = ({ children }: WrapperChild) => {
2 | return (
3 |
4 | {children}
5 |
6 | )
7 | }
8 | export default AccountWrapper
9 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/admin/AddNewProduct.tsx:
--------------------------------------------------------------------------------
1 | import { useParams } from 'next/navigation'
2 | import React, { forwardRef } from 'react'
3 | import { MdAdd } from 'react-icons/md'
4 | import { Button } from '../ui/button'
5 |
6 | const AddNewProduct = forwardRef(({ onClick }: { onClick: () => void }) => {
7 | const { lang } = useParams()
8 |
9 | return (
10 |
18 | )
19 | })
20 |
21 | AddNewProduct.displayName = 'AddNewProduct'
22 |
23 | export default AddNewProduct
24 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/checkout/CheckoutWrapper.tsx:
--------------------------------------------------------------------------------
1 | import CheckoutProvider from '@/providers/CheckoutProvider'
2 | import ReactQueryProvider from '@/providers/QueryProvider'
3 |
4 | const CheckoutWrapper = ({ children }: WrapperChild) => {
5 | return (
6 |
7 |
8 | {children}
9 |
10 |
11 | )
12 | }
13 | export default CheckoutWrapper
14 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/checkout/T&C.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import TermsAndConditionsBengali from './T&CBengali'
3 | import TermsAndConditionsEnglish from './T&CEnglish'
4 |
5 | const TermsAndConditions = ({
6 | isLocaleBengali,
7 | }: {
8 | isLocaleBengali: boolean
9 | }) => {
10 | return (
11 |
12 | {isLocaleBengali ? (
13 |
14 | ) : (
15 |
16 | )}
17 |
18 | )
19 | }
20 |
21 | export default TermsAndConditions
22 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/common/Copyright.tsx:
--------------------------------------------------------------------------------
1 | import { getDictionary } from '@/app/[lang]/dictionaries'
2 | import Image from 'next/image'
3 |
4 | const Copyright = async ({ lang }: ILang) => {
5 | const {
6 | footer: { copyright },
7 | } = await getDictionary(lang)
8 |
9 | return (
10 |
11 |
12 |
{copyright}
13 |
14 |
21 |
22 |
23 |
24 | )
25 | }
26 | export default Copyright
27 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/common/Dropdown.tsx:
--------------------------------------------------------------------------------
1 | import { getDictionary } from '@/app/[lang]/dictionaries'
2 | import { getAllCategories } from '@/db/queries/product.queries'
3 | import StaggeredDropDown from '../ui/staggered-dropdown'
4 |
5 | const Dropdown = async ({ lang }: ILang) => {
6 | const categories: ICategory[] = await getAllCategories()
7 | const { filter } = await getDictionary(lang)
8 | const categoryNames = categories.map((cat) => Object.keys(cat)).flat()
9 |
10 | return (
11 |
16 | )
17 | }
18 | export default Dropdown
19 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/common/HeaderContainer.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import useStickyHeader from '@/hooks/misc-hooks/useStickyHeader'
4 | import { ReactNode } from 'react'
5 |
6 | const HeaderContainer = ({ children }: { children: ReactNode }) => {
7 | const stickyHeader = useStickyHeader()
8 | return (
9 |
16 | )
17 | }
18 | export default HeaderContainer
19 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/common/ScrollProgress.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { motion, useScroll, useSpring } from 'framer-motion'
3 |
4 | const ScrollProgress = () => {
5 | const { scrollYProgress } = useScroll()
6 |
7 | const scaleX = useSpring(scrollYProgress, {
8 | stiffness: 100,
9 | damping: 30,
10 | restDelta: 0.002,
11 | })
12 |
13 | return (
14 |
18 | )
19 | }
20 | export default ScrollProgress
21 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/common/TypeAnimation.tsx:
--------------------------------------------------------------------------------
1 | import { TypeAnimation } from 'react-type-animation'
2 |
3 | const TypeEffect = () => {
4 | // creating sequence by putting the time after each element of array
5 | const sequence = [
6 | 'Outdoor',
7 | 500,
8 | 'Sofa',
9 | 500,
10 | 'Mattress',
11 | 500,
12 | 'Recliner',
13 | 500,
14 | 'Chair',
15 | 500,
16 | ]
17 |
18 | return (
19 |
28 | )
29 | }
30 |
31 | export default TypeEffect
32 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/home/Ads.tsx:
--------------------------------------------------------------------------------
1 | import Image from 'next/image'
2 | import Link from 'next/link'
3 | import AdImage from '../../../public/images/offer.jpg'
4 | import { BackgroundGradient } from '../ui/background-gradient'
5 |
6 | const Ads = () => {
7 | return (
8 |
9 |
10 |
11 |
19 |
20 |
21 |
22 | )
23 | }
24 | export default Ads
25 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/home/Advertising.tsx:
--------------------------------------------------------------------------------
1 | import { getRandomLowDiscountProduct } from '@/db/queries/product.queries'
2 | import RandomAdvertiseText from './RandomAdvertiseText'
3 |
4 | const Advertising = async () => {
5 | const randomDiscountedProduct = await getRandomLowDiscountProduct()
6 |
7 | return (
8 |
9 |
10 |
11 | )
12 | }
13 |
14 | export default Advertising
15 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/product/ProductDescription.tsx:
--------------------------------------------------------------------------------
1 | import { getDictionary } from '@/app/[lang]/dictionaries'
2 |
3 | const ProductDescription = async ({
4 | description,
5 | lang,
6 | }: {
7 | description: string
8 | lang: ILang['lang']
9 | }) => {
10 | const {
11 | productDetailsPage: { productDetails },
12 | } = await getDictionary(lang)
13 | return (
14 |
15 |
16 | {productDetails}
17 |
18 |
23 |
24 | )
25 | }
26 | export default ProductDescription
27 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/product/RelatedProducts.tsx:
--------------------------------------------------------------------------------
1 | import { getDictionary } from '@/app/[lang]/dictionaries'
2 | import Product from './Product'
3 |
4 | const RelatedProducts = async ({
5 | relatedProducts,
6 | lang,
7 | }: {
8 | relatedProducts: IProduct[]
9 | lang: ILang['lang']
10 | }) => {
11 | const {
12 | productDetailsPage: { relatedProd },
13 | } = await getDictionary(lang)
14 |
15 | return (
16 |
17 |
18 | {relatedProd}
19 |
20 |
21 | {relatedProducts.map((product) => (
22 |
23 | ))}
24 |
25 |
26 | )
27 | }
28 | export default RelatedProducts
29 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/shop/AllProducts.tsx:
--------------------------------------------------------------------------------
1 | import { getAllProducts } from '@/db/queries/product.queries'
2 | import createSearchParamsObjectForProducts from '@/utils/createSearchParamsObjectForProducts'
3 | import Product from '../product/Product'
4 |
5 | const AllProducts = async ({
6 | lang,
7 | searchParams,
8 | }: {
9 | lang: ILang['lang']
10 | searchParams: IShopSearchParams
11 | }) => {
12 | const products = await getAllProducts(
13 | createSearchParamsObjectForProducts(searchParams)
14 | )
15 |
16 | return products.map((product: IProduct) => (
17 |
22 | ))
23 | }
24 | export default AllProducts
25 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/shop/DrawerTrigger.tsx:
--------------------------------------------------------------------------------
1 | import { Drawer, DrawerTrigger } from '@/components/ui/drawer'
2 | import { getAllCategories } from '@/db/queries/product.queries'
3 | import { GrDrawer } from 'react-icons/gr'
4 |
5 | const DrawerTriggerBtn = async () => {
6 | const categories: ICategory[] = await getAllCategories()
7 |
8 | const categoryNames = categories.map((cat) => Object.keys(cat)).flat()
9 |
10 | return (
11 |
12 |
13 |
14 | {/* */}
15 |
16 |
17 | )
18 | }
19 |
20 | export default DrawerTriggerBtn
21 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/shop/NoProductMessage.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { useSearchParams } from 'next/navigation'
3 |
4 | const NoProductMessage = () => {
5 | const searchParams = useSearchParams()
6 |
7 | let searchParamString = ''
8 |
9 | for (const [key, value] of searchParams.entries()) {
10 | searchParamString += `[${key} : ${value}]`
11 | }
12 | return (
13 |
14 | No products for your
15 | {searchParamString}
16 |
17 | )
18 | }
19 | export default NoProductMessage
20 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/shop/ProductWrapper.tsx:
--------------------------------------------------------------------------------
1 | const ProductWrapper = ({ children }: WrapperChild) => {
2 | return (
3 |
6 | )
7 | }
8 | export default ProductWrapper
9 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/shop/ResetFilters.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import useSidebarFilter from '@/hooks/product-hooks/useSidebarFilter'
3 | import { useSearchParams } from 'next/navigation'
4 | import { Button } from '../ui/button'
5 |
6 | const ResetFilters = () => {
7 | const searchParams = useSearchParams()
8 | const params = new URLSearchParams(searchParams.toString())
9 |
10 | const { handleReset } = useSidebarFilter()
11 |
12 | return (
13 |
22 | )
23 | }
24 | export default ResetFilters
25 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/shop/ShopWrapper.tsx:
--------------------------------------------------------------------------------
1 | import ReactQueryProvider from '@/providers/QueryProvider'
2 |
3 | const ShopWrapper = ({ children }: WrapperChild) => {
4 | return (
5 |
6 | {children}
7 |
8 | )
9 | }
10 | export default ShopWrapper
11 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/ui/label.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as LabelPrimitive from "@radix-ui/react-label"
5 | import { cva, type VariantProps } from "class-variance-authority"
6 |
7 | import { cn } from "@/lib/utils"
8 |
9 | const labelVariants = cva(
10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
11 | )
12 |
13 | const Label = React.forwardRef<
14 | React.ElementRef,
15 | React.ComponentPropsWithoutRef &
16 | VariantProps
17 | >(({ className, ...props }, ref) => (
18 |
23 | ))
24 | Label.displayName = LabelPrimitive.Root.displayName
25 |
26 | export { Label }
27 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/ui/toast-action.tsx:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 | import { ToastAction } from './toast'
3 |
4 | const ActionOfToast = ({
5 | alt,
6 | text,
7 | link,
8 | }: {
9 | alt: string
10 | text: string
11 | link: string
12 | }) => {
13 | return (
14 |
15 | {text}
16 |
17 | )
18 | }
19 |
20 | export default ActionOfToast
21 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/components/wishlist/WishlistWrapper.tsx:
--------------------------------------------------------------------------------
1 | const WishlistWrapper = ({ children }: WrapperChild) => {
2 | return (
3 |
4 | {children}
5 |
6 | )
7 | }
8 | export default WishlistWrapper
9 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/context/index.ts:
--------------------------------------------------------------------------------
1 | import { createContext } from 'react'
2 |
3 | export const WishlistContext = createContext(
4 | {} as IWishlistContextValue
5 | )
6 |
7 | export const CartContext = createContext(
8 | {} as ICartContextValue
9 | )
10 |
11 | export const FilterContext = createContext({} as IFilterContext)
12 |
13 | export const CheckoutContext = createContext({})
14 |
15 | export const ThemeContext = createContext({} as IThemeContext)
16 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/hooks/context-hooks/useCartContext.ts:
--------------------------------------------------------------------------------
1 | import { CartContext } from '@/context'
2 | import { useContext } from 'react'
3 |
4 | export const useCartContext = () => {
5 | const { userCart, setUserCart } = useContext(CartContext)
6 |
7 | return { userCart, setUserCart }
8 | }
9 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/hooks/context-hooks/useFilterContext.ts:
--------------------------------------------------------------------------------
1 | import { FilterContext } from '@/context'
2 | import { useContext } from 'react'
3 |
4 | const useFilterContext = (): IFilterContext => {
5 | const context = useContext(FilterContext)
6 | if (!context) {
7 | throw new Error('useFilterContext must be used within a FilterProvider')
8 | }
9 | return context
10 | }
11 |
12 | export default useFilterContext
13 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/hooks/context-hooks/useWishlistContext.ts:
--------------------------------------------------------------------------------
1 | import { WishlistContext } from '@/context'
2 | import { useContext } from 'react'
3 |
4 | export const useWishlistContext = () => {
5 | const { userWishlist, setUserWishlist } = useContext(WishlistContext)
6 |
7 | return { userWishlist, setUserWishlist }
8 | }
9 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/hooks/misc-hooks/useDebounce.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from 'react'
2 |
3 | type Callback = (...args: T) => void
4 |
5 | const useDebounce = (
6 | cb: Callback,
7 | wait: number
8 | ): ((...args: T) => void) => {
9 | const timeoutIdRef = useRef(null)
10 |
11 | const debouncedCallback = (...args: T) => {
12 | if (timeoutIdRef.current) {
13 | clearTimeout(timeoutIdRef.current)
14 | }
15 | timeoutIdRef.current = setTimeout(() => {
16 | cb(...args)
17 | }, wait)
18 | }
19 |
20 | useEffect(() => {
21 | return () => {
22 | if (timeoutIdRef.current) {
23 | clearTimeout(timeoutIdRef.current)
24 | }
25 | }
26 | }, [])
27 |
28 | return debouncedCallback
29 | }
30 |
31 | export default useDebounce
32 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/hooks/misc-hooks/useStickyHeader.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react'
2 |
3 | const useStickyHeader = () => {
4 | const [header, setHeader] = useState(false)
5 |
6 | const scrollHeader = () => {
7 | if (window.scrollY >= 500) {
8 | setHeader(true)
9 | } else {
10 | setHeader(false)
11 | }
12 | }
13 |
14 | useEffect(() => {
15 | window.addEventListener('scroll', scrollHeader)
16 |
17 | return () => window.removeEventListener('scroll', scrollHeader)
18 | }, [])
19 |
20 | return header
21 | }
22 | export default useStickyHeader
23 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/hooks/product-hooks/useGetProducts.ts:
--------------------------------------------------------------------------------
1 | import { useQuery } from '@tanstack/react-query'
2 | import axios from 'axios'
3 |
4 | const useGetProducts = () => {
5 | const query = useQuery({
6 | queryKey: ['products'],
7 | queryFn: async () => {
8 | const { data } = await axios.get(
9 | `${process.env.NEXT_PUBLIC_BASE_URL}/api/shop`
10 | )
11 | return data
12 | },
13 | })
14 | return query
15 | }
16 | export default useGetProducts
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/hooks/product-hooks/useGetSingleProduct.ts:
--------------------------------------------------------------------------------
1 | import { useQuery } from '@tanstack/react-query'
2 | import axios from 'axios'
3 |
4 | const useGetSingleProduct = (id: string) => {
5 | const query = useQuery({
6 | queryKey: ['product', id],
7 | queryFn: async () => {
8 | const { data } = await axios.get(
9 | `${process.env.NEXT_PUBLIC_BASE_URL}/api/reviews/${id}`
10 | )
11 | return data
12 | },
13 | })
14 | return query
15 | }
16 | export default useGetSingleProduct
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/hooks/product-hooks/useStock.ts:
--------------------------------------------------------------------------------
1 | import { useQuery } from '@tanstack/react-query'
2 | import axios from 'axios'
3 |
4 | const useStock = (product: IProduct) => {
5 | const query = useQuery({
6 | queryKey: ['stock', product._id],
7 | queryFn: async () =>
8 | await axios.get(
9 | `${process.env.NEXT_PUBLIC_BASE_URL}/api/stock/${product._id}`
10 | ),
11 | refetchInterval: 5000,
12 | enabled: !!product._id,
13 | })
14 | return query
15 | }
16 | export default useStock
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/hooks/wishlist-hooks/useGetUserWishlist.ts:
--------------------------------------------------------------------------------
1 | import { useQuery } from '@tanstack/react-query'
2 | import axios from 'axios'
3 |
4 | const useGetUserWishlist = (userId: string, limit: number) => {
5 | const query = useQuery({
6 | queryKey: ['wishlist', userId],
7 | queryFn: async () => {
8 | const { data } = await axios.get(
9 | `${process.env.NEXT_PUBLIC_BASE_URL}/api/wishlist/${userId}?limit=${limit}`
10 | )
11 | return data
12 | },
13 | enabled: !!userId,
14 | })
15 | return query
16 | }
17 | export default useGetUserWishlist
18 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { type ClassValue, clsx } from "clsx"
2 | import { twMerge } from "tailwind-merge"
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs))
6 | }
7 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/providers/CartProvider.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { CartContext } from '@/context'
3 | import { ReactNode, useState } from 'react'
4 |
5 | const CartProvider = ({ children }: { children: ReactNode }) => {
6 | const [userCart, setUserCart] = useState({
7 | loading: true,
8 | data: [],
9 | error: false,
10 | offlineCart: [],
11 | quantity: { productId: '', quantity: 0 },
12 | })
13 |
14 | return (
15 |
16 | {children}
17 |
18 | )
19 | }
20 | export default CartProvider
21 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/providers/QueryProvider.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
3 | import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
4 | import { useState } from 'react'
5 |
6 | const ReactQueryProvider = ({ children }: { children: React.ReactNode }) => {
7 | const [queryClient] = useState(() => new QueryClient())
8 |
9 | return (
10 |
11 | {children}
12 |
13 |
14 | )
15 | }
16 |
17 | export default ReactQueryProvider
18 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/providers/ThemeProvider.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { LC_THEME_KEY } from '@/utils/constants'
3 | import { ThemeProvider as NextThemeProvider } from 'next-themes'
4 | import { ReactNode, useState } from 'react'
5 |
6 | const ThemeProvider = ({ children }: { children: ReactNode }) => {
7 | let localStorageTheme =
8 | JSON.parse(localStorage.getItem(LC_THEME_KEY) as string) ?? false
9 |
10 | const [isDark, setIsDark] = useState(localStorageTheme)
11 | return (
12 |
13 | {children}
14 |
15 | )
16 | }
17 | export default ThemeProvider
18 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/providers/ToastProvider.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { ToastContainer } from 'react-toastify'
4 | import 'react-toastify/dist/ReactToastify.css'
5 |
6 | interface ToastProviderProps {
7 | children: React.ReactNode
8 | }
9 |
10 | export default function ToastProvider({ children }: ToastProviderProps) {
11 | return (
12 | <>
13 | {children}
14 |
15 | >
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/providers/WishlistProvider.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { WishlistContext } from '@/context'
3 | import { ReactNode, useState } from 'react'
4 |
5 | const WishlistProvider = ({ children }: { children: ReactNode }) => {
6 | const [userWishlist, setUserWishlist] = useState({
7 | loading: true,
8 | data: [],
9 | error: false,
10 | offlineWishlist: [],
11 | })
12 |
13 | return (
14 |
15 | {children}
16 |
17 | )
18 | }
19 | export default WishlistProvider
20 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/barPollUtil.ts:
--------------------------------------------------------------------------------
1 | function getOccurrence(array: any[], value: number) {
2 | var count = 0
3 | array.forEach((v) => v === value && count++)
4 | return count
5 | }
6 |
7 | const getColorForTitle = (title: number): string => {
8 | switch (title) {
9 | case 5:
10 | return 'bg-green-500'
11 | case 4:
12 | return 'bg-fuchsia-500'
13 | case 3:
14 | return 'bg-cyan-500'
15 | case 2:
16 | return 'bg-blue-500'
17 | case 1:
18 | return 'bg-red-500'
19 | default:
20 | return 'bg-gray-500'
21 | }
22 | }
23 |
24 | export { getColorForTitle, getOccurrence }
25 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/checkIfUserExists.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 |
3 | const checkIfUserExists = async (email: string) => {
4 | const { data: status } = await axios.get(
5 | `${process.env.NEXT_PUBLIC_BASE_URL}/api/user/${email}`
6 | )
7 | return status
8 | }
9 | export default checkIfUserExists
10 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/convertNumsToBengali.ts:
--------------------------------------------------------------------------------
1 | const bengaliNums = ['০', '১', '২', '৩', '৪', '৫', '৬', '৭', '৮', '৯']
2 |
3 | export const convertToBengali = (number: number) => {
4 | return number
5 | .toString()
6 | .split('')
7 | .map((digit) => bengaliNums[digit as any])
8 | .join('')
9 | }
10 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/createImgBlur.ts:
--------------------------------------------------------------------------------
1 | const createImgBlur = async (url: string) => {
2 | // plaiceholder gives error with sharp module in prod, so, using a native solution and it works fine
3 | const imageBlur = await fetch(url).then(async (res) => {
4 | return Buffer.from(await res.arrayBuffer()).toString('base64')
5 | })
6 |
7 | return imageBlur
8 | }
9 | export default createImgBlur
10 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/createSearchParamsObjectForProducts.ts:
--------------------------------------------------------------------------------
1 | const createSearchParamsObjectForProducts = (
2 | searchParams: IShopSearchParams
3 | ) => {
4 | const {
5 | category,
6 | min,
7 | max,
8 | query,
9 | size,
10 | color,
11 | limit,
12 | skip,
13 | sort,
14 | stock_status = 'inStock',
15 | } = searchParams
16 | const categories = category?.split(',')
17 |
18 | return {
19 | categories,
20 | min,
21 | max,
22 | size,
23 | query,
24 | color,
25 | limit,
26 | skip,
27 | sort,
28 | inStock: stock_status === 'inStock',
29 | }
30 | }
31 | export default createSearchParamsObjectForProducts
32 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/generatePasswordResetToken.ts:
--------------------------------------------------------------------------------
1 | import { PasswordResetTokenModel } from '@/app/models/passwordResetTokenModel'
2 | import { getPasswordResetTokenByEmail } from '@/db/queries/token.queries'
3 |
4 | export const generatePasswordResetToken = async (email: string) => {
5 | const token = crypto.randomUUID()
6 | // expires after 1 hour
7 | const expires = new Date(new Date().getTime() + 3600 * 1000)
8 |
9 | const existingToken = await getPasswordResetTokenByEmail(email)
10 |
11 | if (existingToken) {
12 | await PasswordResetTokenModel.deleteOne({ _id: existingToken._id })
13 | }
14 |
15 | const passwordResetToken = await PasswordResetTokenModel.create({
16 | email,
17 | token,
18 | expires,
19 | })
20 |
21 | return passwordResetToken
22 | }
23 | export default generatePasswordResetToken
24 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/getAvgReviewStars.tsx:
--------------------------------------------------------------------------------
1 | import { FaStar } from 'react-icons/fa'
2 |
3 | const getAvgReviewStars = (reviews: any[]) => {
4 | return reviews.length > 0
5 | ? Array.from({
6 | length: Math.floor(
7 | reviews?.reduce((acc, curr) => acc + curr.rating, 0)! / reviews.length
8 | ),
9 | }).map((_, i) => (
10 |
11 |
12 |
13 | ))
14 | : null
15 | }
16 | export default getAvgReviewStars
17 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/getCategoryIcons.tsx:
--------------------------------------------------------------------------------
1 | import { FaBed, FaCouch, FaRegBuilding, FaUtensils } from 'react-icons/fa'
2 | import { FaMattressPillow } from 'react-icons/fa6'
3 |
4 | const getCategoryIcon = (category: string) => {
5 | switch (category.toLowerCase()) {
6 | case 'living room':
7 | return
8 | case 'sofa':
9 | return
10 | case 'outdoor':
11 | return
12 | case 'kitchen':
13 | return
14 | case 'mattress':
15 | return
16 | default:
17 | return null
18 | }
19 | }
20 |
21 | export default getCategoryIcon
22 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/getInitialReviewTab.ts:
--------------------------------------------------------------------------------
1 | const getInitialReviewTab = (productReviews: IReviews['reviews']) => {
2 | // find the maximum rating
3 | const maxRating = productReviews.reduce(
4 | (max, review) => (review.rating > max ? review.rating : max),
5 | 0
6 | )
7 |
8 | // convert max rating to index in tabs array
9 | const initialTab = maxRating >= 1 && maxRating <= 5 ? maxRating : 0
10 | return initialTab
11 | }
12 | export default getInitialReviewTab
13 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/getProductDiscountPercentage.ts:
--------------------------------------------------------------------------------
1 | const getProductDiscountPercentage = (
2 | price: number,
3 | discount_price: number
4 | ) => {
5 | return (Math.abs(price - discount_price) / discount_price) * 100
6 | }
7 | export default getProductDiscountPercentage
8 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/getRandomNumber.ts:
--------------------------------------------------------------------------------
1 | export default function getRandomNumber(min: number, max: number) {
2 | return Math.floor(Math.random() * (max - min)) + min
3 | }
4 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/getReviewStars.tsx:
--------------------------------------------------------------------------------
1 | import { FaStar } from 'react-icons/fa'
2 |
3 | const getReviewStars = (review: IReviews['reviews'][0]) => {
4 | return Array.from({ length: review.rating }).map((_, i) => (
5 |
6 | ))
7 | }
8 | export default getReviewStars
9 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/getRndInt.ts:
--------------------------------------------------------------------------------
1 | export default function getRndInteger(min: number, max: number) {
2 | return Math.floor(Math.random() * (max - min)) + min
3 | }
4 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/getSuspenseKey.ts:
--------------------------------------------------------------------------------
1 | export const getSuspenseKey = (searchParams: IShopSearchParams) =>
2 | Object.values(searchParams).join(', ')
3 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/getUniqueCategories.ts:
--------------------------------------------------------------------------------
1 | export const getUniqueCategories = (products: IProduct[]) => {
2 | const categories: string[] = []
3 | products.forEach((product) => {
4 | if (!categories.includes(product.category)) {
5 | categories.push(product.category)
6 | }
7 | })
8 | return categories
9 | }
10 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/headerFetchUtil.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 |
3 | export const fetchUserWishlist = async (userId: string) => {
4 | try {
5 | const { data: wishlist } = await axios.get(
6 | `${process.env.NEXT_PUBLIC_BASE_URL}/api/wishlist/${userId}?limit=${Infinity}` // infinity so show all, a quick solution
7 | )
8 | return await wishlist
9 | } catch (error) {
10 | throw error
11 | }
12 | }
13 | export const fetchUserCart = async (userId: string) => {
14 | try {
15 | const cart = await fetch(
16 | `${process.env.NEXT_PUBLIC_BASE_URL}/api/cart/${userId}`
17 | )
18 | return await cart.json()
19 | } catch (error) {
20 | throw error
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/redirectIfNotLoggedIn.ts:
--------------------------------------------------------------------------------
1 | import { auth } from '@/auth'
2 | import { redirect } from 'next/navigation'
3 |
4 | const redirectIfNotLoggedIn = async () => {
5 | const session = (await auth()) as SessionWith_Id
6 | const userId = session?.user?._id?.toString() ?? session?.user?.id?.toString()
7 |
8 | // if user not logged in, redirect to the login page
9 | if (!userId) {
10 | redirect('/login')
11 | }
12 |
13 | return userId
14 | }
15 | export default redirectIfNotLoggedIn
16 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/revokeAdminIsUsersPages.ts:
--------------------------------------------------------------------------------
1 | import { auth } from '@/auth'
2 | import { notFound } from 'next/navigation'
3 |
4 | const revokeAdminIsUsersPages = async () => {
5 | const session = (await auth()) as SessionWith_Id
6 |
7 | const isAdmin = session?.user?.role === 'admin'
8 |
9 | // if user is not user, and tries to access this page, show the not found page
10 | if (isAdmin) {
11 | notFound()
12 | }
13 | }
14 | export default revokeAdminIsUsersPages
15 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/revokeUserInAdminPanel.ts:
--------------------------------------------------------------------------------
1 | import { auth } from '@/auth'
2 | import { notFound } from 'next/navigation'
3 |
4 | const revokeUserInAdminPanel = async () => {
5 | const session = (await auth()) as SessionWith_Id
6 |
7 | const isAdmin = session?.user?.role === 'admin'
8 |
9 | // if user is not admin, and tries to access this page, show the error page
10 | if (!isAdmin) {
11 | notFound()
12 | }
13 | }
14 | export default revokeUserInAdminPanel
15 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/splitString.ts:
--------------------------------------------------------------------------------
1 | export const splitString = (string: string) => {
2 | const characters = []
3 |
4 | const regex = /[\s\S]/gu
5 |
6 | let match
7 |
8 | while ((match = regex.exec(string)) !== null) {
9 | characters.push(match[0])
10 | }
11 | return characters
12 | }
13 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/uploadthing.ts:
--------------------------------------------------------------------------------
1 | import {
2 | generateUploadButton,
3 | generateUploadDropzone,
4 | } from '@uploadthing/react'
5 |
6 | import type { OurFileRouter } from '@/app/api/uploadthing/core'
7 |
8 | export const UploadButton = generateUploadButton()
9 | export const UploadDropzone = generateUploadDropzone()
10 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/validateBDPhoneNumber.ts:
--------------------------------------------------------------------------------
1 | const validateBDPhoneNumber = (num: string) => {
2 | return String(num).match(/(^(\+88|0088)?(01){1}[3456789]{1}(\d){8})$/)
3 | }
4 | export default validateBDPhoneNumber
5 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/src/utils/validateEmail.ts:
--------------------------------------------------------------------------------
1 | export const validateEmail = (email: string) => {
2 | return String(email)
3 | .toLowerCase()
4 | .match(
5 | /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|.(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/Assignment 10 - LWS Kart/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "target": "es6",
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./src/*"]
23 | }
24 | },
25 | "include": [
26 | "next-env.d.ts",
27 | "**/*.ts",
28 | "**/*.tsx",
29 | ".next/types/**/*.ts",
30 | "src/components/account/PersonalProfileEdit.tsx"
31 | ],
32 | "exclude": ["node_modules"]
33 | }
34 |
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react-refresh/only-export-components': [
16 | 'warn',
17 | { allowConstantExport: true },
18 | ],
19 | 'react/prop-types': 'off',
20 | 'no-unused-vars': 'off',
21 | },
22 | }
23 |
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import BookGrid from "./components/Books/BookGrid";
3 | import Header from "./components/Header/Header";
4 | import Layout from "./components/Layout";
5 |
6 | export default function App() {
7 | const [searchTerm, setSearchTerm] = useState("");
8 | const [sortBy, setSortBy] = useState("");
9 |
10 | const handleSearch = (searchTerm) => {
11 | setSearchTerm(searchTerm);
12 | };
13 |
14 | const handleSort = (sortBy) => {
15 | setSortBy(sortBy);
16 | };
17 |
18 | return (
19 | <>
20 |
21 |
27 |
28 |
29 | >
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/cracking_the_coding_interview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/cracking_the_coding_interview.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/eloquent_js.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/eloquent_js.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/hands_on_r_programming.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/hands_on_r_programming.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/html_n_css.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/html_n_css.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/js_jquery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/js_jquery.png
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/js_the_good_parts.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/js_the_good_parts.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/learn_js_quicky.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/learn_js_quicky.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/learning_js_design_patterns.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/learning_js_design_patterns.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/nodejs_design_pattern.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/nodejs_design_pattern.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/python_crash_course.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/python_crash_course.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/react_key_concept.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/react_key_concept.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/the_js_definitive_guide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/the_js_definitive_guide.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/the_road_to_react.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/the_road_to_react.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/booksImages/think_like_a_programmer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/booksImages/think_like_a_programmer.jpg
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 2 - Book Finder/src/assets/logo.png
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export default function Footer() {
4 | return (
5 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/components/Header/SortBy.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export default function SortBy({ sortBy, handleSort }) {
4 | return (
5 |
6 |
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/components/Layout.jsx:
--------------------------------------------------------------------------------
1 | import Footer from "./Footer";
2 | import Navbar from "./Navbar";
3 |
4 | export default function Layout({ children }) {
5 | return (
6 | <>
7 |
8 | {children}
9 |
10 | >
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [
4 | "./index.html",
5 | "./src/**/*.{js,ts,jsx,tsx}",
6 | ],
7 | theme: {
8 | extend: {},
9 | },
10 | plugins: [],
11 | }
--------------------------------------------------------------------------------
/Assignment 2 - Book Finder/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react-refresh/only-export-components': [
16 | 'warn',
17 | { allowConstantExport: true },
18 | ],
19 | },
20 | }
21 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/src/assets/frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 3 - Improve Tasker/src/assets/frame.png
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/src/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | export default function Footer() {
2 | return (
3 | <>
4 |
12 | >
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/src/components/Header.jsx:
--------------------------------------------------------------------------------
1 | import logo from "../assets/lws-logo-en.svg";
2 |
3 | export default function Header() {
4 | return (
5 | <>
6 |
19 | >
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/src/components/Tasks/TaskHeader.jsx:
--------------------------------------------------------------------------------
1 | import TaskAction from "./TaskAction";
2 | import TaskSearch from "./TaskSearch";
3 |
4 | export default function TaskHeader() {
5 | return (
6 | <>
7 |
8 |
9 | Your Tasks
10 |
11 |
12 |
13 | {/* Renders the task search component */}
14 |
15 |
16 | {/* Renders the task action component (buttons for adding and deleting) */}
17 |
18 |
19 |
20 | >
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | @layer utilities {
6 | td {
7 | @apply p-0;
8 | }
9 |
10 | .container {
11 | @apply px-4 mx-auto;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/src/reducer/actions.js:
--------------------------------------------------------------------------------
1 | // Actions for task manipulation
2 | export const ADDED = 'ADDED'; // Indicates a task has been added
3 | export const UPDATED = 'UPDATED'; // Indicates a task has been updated
4 | export const DELETED = 'DELETED'; // Indicates a task has been deleted
5 | export const ALL_DELETE = 'ALL_DELETE'; // Indicates all tasks have been deleted
6 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/src/ui/Button.jsx:
--------------------------------------------------------------------------------
1 | // Reusable button component with customization options
2 | export default function Button({ bg, children, ...extraAttr }) {
3 | return (
4 | <>
5 |
11 | >
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/src/ui/Tag.jsx:
--------------------------------------------------------------------------------
1 | export default function Tag({ tag, color }) {
2 | return (
3 | <>
4 |
5 |
8 | {tag}
9 |
10 |
11 | >
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/src/utils/generateColor.js:
--------------------------------------------------------------------------------
1 | const HEX_BASE_NUMBER = parseInt('ffffff', 16) // ffffff means white color hex to convert integer value. just for a maintain hex code order
2 |
3 | export default function generateColor() {
4 | return `#${Math.floor(Math.random() * HEX_BASE_NUMBER).toString(16)}` // use this HEX_BASE_NUMBER Size make a random Hexadecimal Number with of color code.
5 | }
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/src/utils/generateId.js:
--------------------------------------------------------------------------------
1 | export default function generateId(tasks = []) {
2 | // Find the highest existing ID among the tasks using the reduce method
3 | const nextId = tasks.reduce((prev, curr) => (prev.id > curr.id ? prev : curr)).id;
4 |
5 | // Return the next available ID, which is one greater than the highest existing ID
6 | return nextId + 1;
7 | }
8 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [
4 | "index.html",
5 | "./src/**/*.{js,jsx,ts,tsx}"
6 | ],
7 | theme: {
8 | extend: {},
9 | },
10 | plugins: [],
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/template/assets/frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 3 - Improve Tasker/template/assets/frame.png
--------------------------------------------------------------------------------
/Assignment 3 - Improve Tasker/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/.env:
--------------------------------------------------------------------------------
1 | VITE_API_URL=http://localhost:8000/v2/
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react/jsx-no-target-blank': 'off',
16 | 'react-refresh/only-export-components': [
17 | 'warn',
18 | { allowConstantExport: true },
19 | ],
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "newsapi",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node main.js"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "cors": "^2.8.5",
14 | "express": "^4.18.2",
15 | "nodemon": "^3.0.3"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/App.jsx:
--------------------------------------------------------------------------------
1 | import Page from './Page.jsx'
2 | import NewsProvider from './provider/NewsProvider.jsx'
3 | import SearchProvider from './provider/SearchProvider.jsx'
4 | import ThemeProvider from './provider/ThemeProvider.jsx'
5 |
6 | const App = () => {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | )
16 | }
17 | export default App
18 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/assets/fonts/publico-headline-web/Publico-Headline-Web-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 4 - News Feeder/src/assets/fonts/publico-headline-web/Publico-Headline-Web-Bold.ttf
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/assets/fonts/tt-commons/TTCommonsRegular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 4 - News Feeder/src/assets/fonts/tt-commons/TTCommonsRegular.otf
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/assets/fonts/tt-commons/TTCommonsSemiBold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 4 - News Feeder/src/assets/fonts/tt-commons/TTCommonsSemiBold.otf
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/assets/icons/search.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 4 - News Feeder/src/assets/logo.png
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/assets/logo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 4 - News Feeder/src/assets/logo_light.png
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/assets/thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 4 - News Feeder/src/assets/thumb.png
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/assets/thumb_lg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 4 - News Feeder/src/assets/thumb_lg.png
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/components/FooterBottom.jsx:
--------------------------------------------------------------------------------
1 | const FooterBottom = () => {
2 | return (
3 |
4 |
5 | Copyright ©2023 | All rights reserved by Learn with Sumit
6 |
7 |
8 | )
9 | }
10 | export default FooterBottom
11 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/components/Navbar/NavDate.jsx:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import { ThemeContext } from '../../context/index.js'
3 | import { getCurrentDate } from '../../utils/getCurrentDate.js'
4 | import SVG from './SVG.jsx'
5 |
6 | const NavDate = () => {
7 | const formattedDate = getCurrentDate()
8 | const { isDark } = useContext(ThemeContext)
9 |
10 | return (
11 |
12 |
13 |
14 | {formattedDate}
15 |
16 |
17 | )
18 | }
19 | export default NavDate
20 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/components/News/LeftNews.jsx:
--------------------------------------------------------------------------------
1 | const LeftNews = ({ children }) => {
2 | return (
3 |
4 | {children}
5 |
6 | )
7 | }
8 | export default LeftNews
9 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/components/News/Loader.jsx:
--------------------------------------------------------------------------------
1 | const Loader = () => {
2 | return (
3 |
6 | )
7 | }
8 |
9 | export default Loader
10 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/components/News/NewsItem.jsx:
--------------------------------------------------------------------------------
1 | import Info from './Info.jsx'
2 | import Thumbnail from './Thumbnail.jsx'
3 |
4 | const NewsItem = ({ left, right, article }) => {
5 | const { urlToImage, content, author } = article
6 |
7 | if (left) {
8 | return (
9 |
10 |
11 |
12 |
13 | )
14 | }
15 |
16 | if (right) {
17 | return (
18 |
19 |
20 |
21 | )
22 | }
23 | }
24 | export default NewsItem
25 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/components/News/RightNews.jsx:
--------------------------------------------------------------------------------
1 | const RightNews = ({ children }) => {
2 | return (
3 |
6 | )
7 | }
8 | export default RightNews
9 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/components/News/Thumbnail.jsx:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import { ThemeContext } from '../../context/index.js'
3 |
4 | const Thumbnail = ({ imgUrl, content, author }) => {
5 | const { isDark } = useContext(ThemeContext)
6 |
7 | return (
8 |
9 | {imgUrl &&

}
10 | {imgUrl && author && (
11 |
16 | Illustration: {author?.startsWith('By') ? 'Amir Vera' : author}
17 |
18 | )}
19 |
{content}
20 |
21 | )
22 | }
23 | export default Thumbnail
24 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/components/NewsLetter.jsx:
--------------------------------------------------------------------------------
1 | const NewsLetter = () => {
2 | return (
3 |
4 |
5 |
6 | Subscribe and be informed first hand about the actual economic news.
7 |
8 |
9 | All the day's headlines and highlights, direct to you every morning..
10 |
11 |
12 | {/* subscribe */}
13 |
16 |
17 | )
18 | }
19 | export default NewsLetter
20 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/constants/constant.js:
--------------------------------------------------------------------------------
1 | export const FOOTER_LINKS = {
2 | 1: [
3 | 'Home',
4 | 'EU Finance',
5 | 'Capital Market',
6 | 'World Economy',
7 | 'Opinion',
8 | 'Finance',
9 | ],
10 | 2: ['Business', 'Agriculture', 'Sport Economy', 'Blog', 'Podcats', 'Video'],
11 | 3: [
12 | 'Terms of Use',
13 | 'Privacy',
14 | 'Cookies Policy',
15 | 'Manage Cookies',
16 | 'Accessibility',
17 | 'Contact Us',
18 | ],
19 | }
20 |
21 | export const CATEGORIES = [
22 | 'General',
23 | 'Business',
24 | 'Entertainment',
25 | 'Health',
26 | 'Science',
27 | 'Sports',
28 | 'Technology',
29 | ]
30 |
31 | export const INITIAL_CATEGORY = 'general'
32 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/context/index.js:
--------------------------------------------------------------------------------
1 | import { createContext } from 'react'
2 |
3 | const NewsContext = createContext(null)
4 | const SearchContext = createContext(null)
5 | const ThemeContext = createContext(null)
6 |
7 | export { NewsContext, SearchContext, ThemeContext }
8 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/hooks/useDebounce.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from 'react'
2 |
3 | const useDebounce = (cb, wait) => {
4 | const timeoutIdRef = useRef(null)
5 |
6 | const debouncedCallback = (...args) => {
7 | if (timeoutIdRef.current) {
8 | clearTimeout(timeoutIdRef.current)
9 | }
10 | timeoutIdRef.current = setTimeout(() => {
11 | cb(...args)
12 | }, wait)
13 | }
14 |
15 | useEffect(() => {
16 | return () => {
17 | if (timeoutIdRef.current) {
18 | clearTimeout(timeoutIdRef.current)
19 | }
20 | }
21 | }, [])
22 | return debouncedCallback
23 | }
24 | export default useDebounce
25 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 |
10 | )
11 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/provider/NewsProvider.jsx:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import { NewsContext, SearchContext } from '../context/index.js'
3 | import useNewsQuery from '../hooks/useNewsQuery.js'
4 |
5 | const NewsProvider = ({ children }) => {
6 | const { searchValue } = useContext(SearchContext)
7 | const { newsData, setNewsData, loading, setCategory, category, error } =
8 | useNewsQuery(searchValue)
9 | return (
10 |
21 | {children}
22 |
23 | )
24 | }
25 | export default NewsProvider
26 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/provider/SearchProvider.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import { SearchContext } from '../context/index.js'
3 |
4 | const SearchProvider = ({ children }) => {
5 | const [searchValue, setSearchValue] = useState('')
6 | return (
7 |
13 | {children}
14 |
15 | )
16 | }
17 | export default SearchProvider
18 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/provider/ThemeProvider.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import { ThemeContext } from '../context/index.js'
3 |
4 | const ThemeProvider = ({ children }) => {
5 | const [isDark, setIsDark] = useState()
6 |
7 | return (
8 |
14 | {children}
15 |
16 | )
17 | }
18 | export default ThemeProvider
19 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/provider/index.js:
--------------------------------------------------------------------------------
1 | import NewsProvider from './NewsProvider.jsx'
2 |
3 | export { NewsProvider }
4 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/utils/formatDate.js:
--------------------------------------------------------------------------------
1 | export const formatDate = (publishedAt) => {
2 | const date = new Date(publishedAt)
3 | const options = { day: '2-digit', month: 'short', year: 'numeric' }
4 | const formattedDate = date.toLocaleDateString('en-US', options)
5 | return formattedDate
6 | }
7 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/src/utils/getCurrentDate.js:
--------------------------------------------------------------------------------
1 | export const getCurrentDate = () => {
2 | const currentDate = new Date()
3 | const options = {
4 | weekday: 'long',
5 | year: 'numeric',
6 | month: 'long',
7 | day: 'numeric',
8 | }
9 | const formattedDate = currentDate.toLocaleDateString('en-US', options)
10 | return formattedDate
11 | }
12 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [
4 | "./index.html",
5 | "./src/**/*.{js,ts,jsx,tsx}",
6 | ],
7 | theme: {
8 | extend: {
9 | container: {
10 | center: true,
11 | },
12 | colors: {
13 | clifford: "#da373d",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | }
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Assignment 4 - News Feeder/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/.env:
--------------------------------------------------------------------------------
1 | VITE_BASE_URL=http://localhost:3000/
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react/jsx-no-target-blank': 'off',
16 | 'react-refresh/only-export-components': [
17 | 'warn',
18 | { allowConstantExport: true },
19 | ],
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | React Blogify | Learn with Sumit
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 5 - React Blogify/src/assets/avatar.png
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/blogs/React-Roadmap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 5 - React Blogify/src/assets/blogs/React-Roadmap.jpg
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/blogs/Underrated Video.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 5 - React Blogify/src/assets/blogs/Underrated Video.jpg
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/blogs/taiulwind-cn-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 5 - React Blogify/src/assets/blogs/taiulwind-cn-thumb.jpg
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/fonts/Europa-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 5 - React Blogify/src/assets/fonts/Europa-Bold.woff
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/fonts/Europa-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 5 - React Blogify/src/assets/fonts/Europa-Bold.woff2
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/fonts/Europa-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 5 - React Blogify/src/assets/fonts/Europa-Regular.woff
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/fonts/Europa-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 5 - React Blogify/src/assets/fonts/Europa-Regular.woff2
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/icons/close.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/icons/comment.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/icons/delete.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/icons/edit.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/icons/heart-filled.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/icons/heart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/icons/search.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/image.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 5 - React Blogify/src/assets/image.avif
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/picture.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/assets/play.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/components/Profile/ActionButton.jsx:
--------------------------------------------------------------------------------
1 | const ActionButton = ({ className, children, cb }) => {
2 | return (
3 |
9 | )
10 | }
11 | export default ActionButton
12 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/components/auth/FormRow.jsx:
--------------------------------------------------------------------------------
1 | const FormRow = ({ label, children, htmlFor, error }) => {
2 | return (
3 |
4 | {label && (
5 |
8 | )}
9 | {children}
10 | {Boolean(error) && (
11 |
12 | {error.message}
13 |
14 | )}
15 |
16 | )
17 | }
18 | export default FormRow
19 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/components/common/Avatar.jsx:
--------------------------------------------------------------------------------
1 | import { BASE_URL } from '../../constants.js'
2 |
3 | const Avatar = ({ avatar, ...props }) => {
4 | return avatar ? (
5 |
6 | ) : (
7 | {props.firstName[0]}
8 | )
9 | }
10 | export default Avatar
11 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/components/common/ScrollToTopOnRouteChange.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { useLocation } from 'react-router-dom'
3 |
4 | export const ScrollToTopOnRouteChange = () => {
5 | const { pathname } = useLocation()
6 |
7 | useEffect(() => {
8 | window.scrollTo(0, 0) // when path changes, scroll to top
9 | }, [pathname])
10 |
11 | return null
12 | }
13 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/components/homepage/BlogContainer.jsx:
--------------------------------------------------------------------------------
1 | const BlogContainer = ({ children }) => {
2 | return (
3 |
4 | {/* Begin Blogs */}
5 |
6 |
7 |
8 | {children}
9 |
10 |
11 |
12 |
13 | )
14 | }
15 | export default BlogContainer
16 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/components/homepage/BlogSidebar.jsx:
--------------------------------------------------------------------------------
1 | import FavoriteBlogs from './FavoriteBlogs.jsx'
2 | import PopularBlogs from './PopularBlogs.jsx'
3 |
4 | const BlogSidebar = () => {
5 | return (
6 |
14 | )
15 | }
16 | export default BlogSidebar
17 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/components/homepage/PopularSkeleton.jsx:
--------------------------------------------------------------------------------
1 | const PopularSkeleton = () => {
2 | return (
3 |
8 | )
9 | }
10 | export default PopularSkeleton
11 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/context/index.js:
--------------------------------------------------------------------------------
1 | import { createContext } from 'react'
2 |
3 | const AuthContext = createContext(null)
4 | const FavoriteContext = createContext(null)
5 | const SearchContext = createContext(null)
6 |
7 | export { AuthContext, FavoriteContext, SearchContext }
8 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/api/useClearAllFav.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from '@tanstack/react-query'
2 | import useAxios from './useAxios.js'
3 |
4 | const useClearAllFav = () => {
5 | const customFetch = useAxios()
6 |
7 | const mutation = useMutation({
8 | mutationFn: async (favorites) => {
9 | try {
10 | favorites.forEach((fav) =>
11 | customFetch.patch(`blogs/${fav.id}/favourite`)
12 | )
13 | } catch (error) {
14 | return error
15 | }
16 | },
17 | })
18 | return mutation
19 | }
20 | export default useClearAllFav
21 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/api/useComment.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from '@tanstack/react-query'
2 | import useAxios from './useAxios.js'
3 |
4 | const useComment = () => {
5 | const customFetch = useAxios()
6 | const mutation = useMutation({
7 | mutationFn: async ({ blogId, content }) =>
8 | customFetch.post(`blogs/${blogId}/comment`, { content }),
9 | })
10 |
11 | const deleteMutation = useMutation({
12 | mutationFn: async ({ blogId, commentId }) =>
13 | customFetch.delete(`blogs/${blogId}/comment/${commentId}`),
14 | })
15 |
16 | return { mutation, deleteMutation }
17 | }
18 | export default useComment
19 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/api/useGetLikedUsers.js:
--------------------------------------------------------------------------------
1 | import { useQueries } from '@tanstack/react-query'
2 | import customFetch from '../../utils/customFetch.js'
3 |
4 | const useGetLikedUsers = (likes) => {
5 | // using the likes array ids to fetch the users to populate the tooltip to show which users liked the blog
6 | const results = useQueries({
7 | queries: likes.map((data) => ({
8 | queryKey: ['like', data.id],
9 | queryFn: async () => await customFetch.get(`profile/${data.id}`),
10 | })),
11 | // return the combined results of each query
12 | combine: (results) => {
13 | return {
14 | data: results.map((result) => result.data),
15 | pending: results.some((result) => result.isPending),
16 | }
17 | },
18 | })
19 | return results
20 | }
21 | export default useGetLikedUsers
22 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/api/useGetPopular.js:
--------------------------------------------------------------------------------
1 | import { useQuery } from '@tanstack/react-query'
2 | import customFetch from '../../utils/customFetch.js'
3 |
4 | const getPopular = async () => {
5 | try {
6 | const data = customFetch.get('blogs/popular')
7 | return data
8 | } catch (error) {
9 | return error
10 | }
11 | }
12 |
13 | const useGetPopular = () => {
14 | const query = useQuery({
15 | queryKey: ['popular-blogs'],
16 | queryFn: getPopular,
17 | })
18 |
19 | return query
20 | }
21 | export default useGetPopular
22 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/api/useGetSingleBlog.js:
--------------------------------------------------------------------------------
1 | import { useQuery } from '@tanstack/react-query'
2 | import customFetch from '../../utils/customFetch.js'
3 |
4 | const getSingleBlog = async (blogId) => {
5 | try {
6 | const data = customFetch.get(`blogs/${blogId}`)
7 | return data
8 | } catch (error) {
9 | return error
10 | }
11 | }
12 |
13 | const useGetSingleBlog = (blogId) => {
14 | const query = useQuery({
15 | queryKey: ['single-blog', blogId],
16 | queryFn: () => getSingleBlog(blogId),
17 | })
18 |
19 | return query
20 | }
21 | export default useGetSingleBlog
22 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/api/useGetUser.js:
--------------------------------------------------------------------------------
1 | import { useQuery } from '@tanstack/react-query'
2 | import useAxios from './useAxios.js'
3 |
4 | const useGetUser = (id) => {
5 | const customFetch = useAxios()
6 |
7 | const query = useQuery({
8 | queryKey: ['user', id],
9 | queryFn: async () => {
10 | try {
11 | return customFetch.get(`profile/${id}`)
12 | } catch (error) {
13 | return error
14 | }
15 | },
16 | })
17 |
18 | return query
19 | }
20 | export default useGetUser
21 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/api/useLoginUser.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from '@tanstack/react-query'
2 | import customFetch from '../../utils/customFetch.js'
3 |
4 | const loginUser = async (user) => {
5 | try {
6 | return customFetch.post('auth/login', user)
7 | } catch (error) {
8 | return error
9 | }
10 | }
11 |
12 | const useLoginUser = () => {
13 | const mutation = useMutation({
14 | mutationFn: (user) => loginUser(user),
15 | })
16 | return mutation
17 | }
18 | export default useLoginUser
19 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/api/useRegisterUser.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from '@tanstack/react-query'
2 | import customFetch from '../../utils/customFetch.js'
3 |
4 | const registerUser = async (newUserDetails) => {
5 | try {
6 | return customFetch.post('auth/register', newUserDetails)
7 | } catch (error) {
8 | return error
9 | }
10 | }
11 |
12 | const useRegisterUser = () => {
13 | const mutation = useMutation({
14 | mutationFn: (newUserDetails) => registerUser(newUserDetails),
15 | })
16 | return mutation
17 | }
18 | export default useRegisterUser
19 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/api/useSearch.js:
--------------------------------------------------------------------------------
1 | import { useQuery } from '@tanstack/react-query'
2 | import useAxios from './useAxios.js'
3 |
4 | const useSearch = (q) => {
5 | const customFetch = useAxios()
6 | const query = useQuery({
7 | queryKey: ['search', q],
8 | queryFn: async () => {
9 | try {
10 | return customFetch.get(`search?q=${q}`)
11 | } catch (error) {
12 | return error
13 | }
14 | },
15 | enabled: !!q,
16 | retry: 0,
17 | })
18 | return query
19 | }
20 | export default useSearch
21 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/useAuth.js:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import { AuthContext } from '../context/index.js'
3 |
4 | const useAuth = () => {
5 | return useContext(AuthContext)
6 | }
7 | export default useAuth
8 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/useDebounce.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from 'react'
2 |
3 | const useDebounce = (cb, wait) => {
4 | const timeoutIdRef = useRef(null)
5 |
6 | const debouncedCallback = (...args) => {
7 | if (timeoutIdRef.current) {
8 | clearTimeout(timeoutIdRef.current)
9 | }
10 | timeoutIdRef.current = setTimeout(() => {
11 | cb(...args)
12 | }, wait)
13 | }
14 |
15 | useEffect(() => {
16 | return () => {
17 | if (timeoutIdRef.current) {
18 | clearTimeout(timeoutIdRef.current)
19 | }
20 | }
21 | }, [])
22 | return debouncedCallback
23 | }
24 | export default useDebounce
25 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/hooks/usePortal.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react'
2 |
3 | const usePortal = () => {
4 | const [showModal, setShowModal] = useState(false)
5 |
6 | useEffect(() => {
7 | // disable the scroll bar when user opens modal
8 | if (showModal) document.body.style.overflow = 'hidden'
9 | else document.body.style.overflow = 'visible'
10 | })
11 |
12 | const handleShowModal = (bool) => {
13 | setShowModal(bool)
14 | }
15 |
16 | return { showModal, handleShowModal }
17 | }
18 | export default usePortal
19 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/pages/Blog.jsx:
--------------------------------------------------------------------------------
1 | import BlogContainer from '../components/homepage/BlogContainer.jsx'
2 | import BlogContent from '../components/homepage/BlogContent.jsx'
3 | import BlogSidebar from '../components/homepage/BlogSidebar.jsx'
4 |
5 | const Blog = () => {
6 | return (
7 |
8 |
9 |
10 |
11 | )
12 | }
13 | export default Blog
14 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/providers/AuthProvider.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import { AuthContext } from '../context/index.js'
3 |
4 | const AuthProvider = ({ children }) => {
5 | const [auth, setAuth] = useState({})
6 |
7 | return (
8 |
9 | {children}
10 |
11 | )
12 | }
13 |
14 | export default AuthProvider
15 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/providers/FavoriteProvider.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import { FavoriteContext } from '../context/index.js'
3 |
4 | const FavoriteProvider = ({ children }) => {
5 | // local storage implemented so the user can add to favorites even if they are offline
6 | const localFavorites = JSON.parse(localStorage.getItem('favoriteBlogs')) || []
7 |
8 | const [favorites, setFavorites] = useState(localFavorites) // inititally local storage favorites are set
9 |
10 | return (
11 |
14 | {children}
15 |
16 | )
17 | }
18 |
19 | export default FavoriteProvider
20 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/providers/SearchProvider.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import { SearchContext } from '../context/index.js'
3 | import usePortal from '../hooks/usePortal.js'
4 |
5 | const SearchProvider = ({ children }) => {
6 | const [query, setQuery] = useState(null)
7 |
8 | const { showModal, handleShowModal } = usePortal()
9 |
10 | return (
11 |
14 | {children}
15 |
16 | )
17 | }
18 |
19 | export default SearchProvider
20 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/utils/customFetch.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { BASE_URL } from '../constants.js'
3 |
4 | const customFetch = axios.create({
5 | baseURL: BASE_URL,
6 | })
7 |
8 | export default customFetch
9 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/utils/formatDate.js:
--------------------------------------------------------------------------------
1 | export const formatDate = (dateString) => {
2 | const date = new Date(dateString)
3 | const options = { month: 'long', day: 'numeric', year: 'numeric' }
4 | return date.toLocaleString('en-US', options)
5 | }
6 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/utils/generateFullName.js:
--------------------------------------------------------------------------------
1 | export const generateFullName = (first, last) => {
2 | let fullName
3 | if (first && last) {
4 | fullName = first + ' ' + last
5 | }
6 | return fullName
7 | }
8 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/utils/getBlogs.js:
--------------------------------------------------------------------------------
1 | import customFetch from './customFetch.js'
2 |
3 | export const getBlogs = async (page) => {
4 | try {
5 | const data = await customFetch.get(`blogs?page=${page}&limit=10`) // show 10 blogs per page
6 | return data
7 | } catch (error) {
8 | return error
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/utils/getLikeCountString.js:
--------------------------------------------------------------------------------
1 | export const getLikeCountString = (likes) => {
2 | return likes.length === 0
3 | ? 'No Likes'
4 | : likes.length === 1
5 | ? '1 Like'
6 | : `${likes.length} Likes`
7 | }
8 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/utils/handleOutsideClick.js:
--------------------------------------------------------------------------------
1 | const handleOutsideClick = (e, ref, setterFn) => {
2 | if (ref.current && !ref.current.contains(e.target)) {
3 | setterFn(false)
4 | }
5 | }
6 |
7 | export default handleOutsideClick
8 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/src/utils/uploadImage.js:
--------------------------------------------------------------------------------
1 | export const uploadImage = async (fileInputRef, toast, mutation) => {
2 | try {
3 | const formData = new FormData()
4 | const file = fileInputRef.current.files[0]
5 |
6 | if (!file) return // if there is no file then don't upload
7 |
8 | formData.append('avatar', file)
9 |
10 | mutation.mutate(formData, {
11 | onSuccess: () => {
12 | toast.success('Profile picture updated', {
13 | autoClose: 1000,
14 | })
15 | },
16 | })
17 | } catch (error) {
18 | toast.error('Error uploading profile picture')
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
4 |
5 | theme: {
6 | extend: {
7 | container: {
8 | center: true,
9 | padding: '1.25rem',
10 | },
11 | colors: {
12 | dark: '#121416',
13 | },
14 | },
15 | },
16 | plugins: [],
17 | }
18 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/vercel.json:
--------------------------------------------------------------------------------
1 | { "routes": [{ "src": "/[^.]+", "dest": "/", "status": 200 }] }
2 |
--------------------------------------------------------------------------------
/Assignment 5 - React Blogify/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 | /.vscode
3 |
4 | # dependencies
5 | /node_modules
6 | /.pnp
7 | .pnp.js
8 | .yarn/install-state.gz
9 |
10 | # testing
11 | /coverage
12 |
13 | # next.js
14 | /.next/
15 | /out/
16 |
17 | # production
18 | /build
19 |
20 | # misc
21 | .DS_Store
22 | *.pem
23 |
24 | # debug
25 | npm-debug.log*
26 | yarn-debug.log*
27 | yarn-error.log*
28 |
29 | # local env files
30 | .env*.local
31 |
32 | # vercel
33 | .vercel
34 |
35 | # typescript
36 | *.tsbuildinfo
37 | next-env.d.ts
38 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/Data/index.js:
--------------------------------------------------------------------------------
1 | import { categories, products } from "./database";
2 |
3 | export function getProducts(
4 | { category, count } = { category: null, count: null }
5 | ) {
6 | const sliceCount = count && count > 0 ? count : products.length;
7 |
8 | if (category && categories.includes(category)) {
9 | return products
10 | .filter((product) => product.category === category)
11 | .slice(0, sliceCount);
12 | }
13 |
14 | return products.slice(0, sliceCount);
15 | }
16 |
17 | export function getProduct({ id }) {
18 | const product = products.find((product) => {
19 | return product.id.toString() === id.toString();
20 | });
21 | return product;
22 | }
23 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/app/(withFooter)/categories/[category]/page.js:
--------------------------------------------------------------------------------
1 | import ProductList from "@/components/ProductList";
2 | import { categories } from "@/Data/database";
3 | import React from "react";
4 |
5 | export function generateStaticParams() {
6 | return categories.map((c) => ({ category: c }));
7 | }
8 |
9 | export function generateMetadata({ params: { category } }) {
10 | return {
11 | title: `${category} | Shop Center`,
12 | description: `page with all ${category} product`,
13 | };
14 | }
15 |
16 | function page({ params: { category } }) {
17 | return ;
18 | }
19 |
20 | export default page;
21 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/app/(withFooter)/categories/page.js:
--------------------------------------------------------------------------------
1 | import ProductList from "@/components/ProductList";
2 | import React from "react";
3 |
4 | export const metadata = {
5 | title: "Shop Center | All Categories",
6 | description: "home for project shop center",
7 | };
8 |
9 | function page() {
10 | return ;
11 | }
12 |
13 | export default page;
14 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/app/(withFooter)/page.js:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 | import Hero from "@/components/Home/Hero";
3 | import ProductList from "@/components/ProductList";
4 |
5 | export const metadata = {
6 | title: "Shop Center | Home",
7 | description: "home for project shop center",
8 | };
9 |
10 | export default function Home() {
11 | return (
12 | <>
13 |
14 |
15 |
20 |
21 | >
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/app/favicon.ico
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/app/layout.js:
--------------------------------------------------------------------------------
1 | import { Inter } from "next/font/google";
2 | import "./globals.css";
3 | import Navbar from "@/components/Navbar";
4 |
5 | const inter = Inter({ subsets: ["latin"] });
6 |
7 | export const metadata = {
8 | title: "Create Next App",
9 | description: "Generated by create next app",
10 | };
11 |
12 | export default function RootLayout({ children }) {
13 | return (
14 |
15 |
16 |
17 | {children}
18 |
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/header.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/header.webp
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/product-1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/product-1.webp
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/product-1s.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/product-1s.webp
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/product-2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/product-2.webp
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/product-3-hover.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/product-3-hover.webp
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/product-3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/product-3.webp
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/product-4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/product-4.webp
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/product-5-front.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/product-5-front.webp
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/product-5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/product-5.webp
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/products/iphone-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/products/iphone-2.jpg
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/products/iphone-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/products/iphone-3.jpg
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/products/iphone-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/products/iphone-4.jpg
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/products/iphone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/products/iphone.jpg
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/products/macbook-pro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/products/macbook-pro.png
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/products/perfume.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/products/perfume.jpg
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/products/samsung-galaxy-book.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 6 - Shop Center/assets/products/samsung-galaxy-book.jpg
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/svg/avatar.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/svg/menu.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/svg/plus.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/svg/star.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/assets/svg/tick.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/components/Home/Hero.jsx:
--------------------------------------------------------------------------------
1 | import heroBg from "@/assets/header.webp";
2 |
3 | function Hero() {
4 | return (
5 |
19 | );
20 | }
21 |
22 | export default Hero;
23 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/components/NavLink.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import Link from "next/link";
3 | import { usePathname } from "next/navigation";
4 |
5 | function NavLink({ href, className, children, ...rest }) {
6 | const pathName = usePathname();
7 |
8 | const formattedClassName =
9 | pathName === href ? className + " border-b" : className;
10 |
11 | return (
12 |
13 | {children}
14 |
15 | );
16 | }
17 |
18 | export default NavLink;
19 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/components/ProductList.jsx:
--------------------------------------------------------------------------------
1 | import { getProducts } from "@/Data";
2 | import ProductComp from "./ProductComp";
3 |
4 | function ProductList({ category = null, count = null }) {
5 | const products = getProducts({ category, count });
6 |
7 | return products.map((product) => (
8 |
9 | ));
10 | }
11 |
12 | export default ProductList;
13 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "paths": {
4 | "@/*": ["./*"]
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | images: {
4 | remotePatterns: [
5 | {
6 | protocol: "https",
7 | hostname: "cdn.dummyjson.com",
8 | pathname: "/**",
9 | },
10 | ],
11 | },
12 | };
13 |
14 | export default nextConfig;
15 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "assignment-6",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "framer-motion": "^11.0.20",
13 | "next": "14.1.4",
14 | "react": "^18",
15 | "react-dom": "^18"
16 | },
17 | "devDependencies": {
18 | "autoprefixer": "^10.0.1",
19 | "eslint": "^8",
20 | "eslint-config-next": "14.1.4",
21 | "postcss": "^8",
22 | "tailwindcss": "^3.3.0"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | "./pages/**/*.{js,ts,jsx,tsx,mdx}",
5 | "./components/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./app/**/*.{js,ts,jsx,tsx,mdx}",
7 | ],
8 | theme: {
9 | extend: {
10 | backgroundImage: {
11 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
12 | "gradient-conic":
13 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | };
19 |
--------------------------------------------------------------------------------
/Assignment 6 - Shop Center/utils/minusPercentage.js:
--------------------------------------------------------------------------------
1 | export function minusPercentage(value, percentage) {
2 | const per = value * (percentage / 100);
3 |
4 | return value - per;
5 | }
6 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/[lang]/@home/default.jsx:
--------------------------------------------------------------------------------
1 | const Default = () => {
2 | return null;
3 | }
4 |
5 | export default Default;
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/[lang]/@home/page.jsx:
--------------------------------------------------------------------------------
1 | import MovieCard from "@/app/_components/home/MovieCard";
2 | const movies = () => import("@/data/data.json").then((res) => res.default);
3 | export default async function Home({ params: { lang } }) {
4 | const data = await movies();
5 |
6 | return (
7 |
8 |
9 |
10 | {data?.results?.map((movie) => (
11 |
12 | ))}
13 |
14 |
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/[lang]/@movie/default.jsx:
--------------------------------------------------------------------------------
1 | const Default = () => {
2 | return null;
3 | };
4 |
5 | export default Default;
6 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/[lang]/_dictionaries/bn.json:
--------------------------------------------------------------------------------
1 | {
2 | "trending": "ট্রেন্ডিং",
3 | "new releases": "নতুন মুক্তিপ্রাপ্তি",
4 | "coming soon": "শীঘ্রই আসছে",
5 | "favorites": "প্রিয়",
6 | "watch later": "পরে দেখুন",
7 | "details": "বিস্তারিত",
8 | "stream in hd": "এইচডি দিয়ে স্ট্রিম করুন",
9 | "download in hd": "এইচডি দিয়ে ডাউনলোড করুন",
10 | "release date": "রিলিজ তারিখ",
11 | "average vote": "গড় ভোট",
12 | "vote count": "ভোট সংখ্যা",
13 | "popularity": "জনপ্রিয়তা"
14 | }
15 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/[lang]/_dictionaries/dictionaries.js:
--------------------------------------------------------------------------------
1 | import "server-only";
2 |
3 | const dictionaries = {
4 | en: () => import("./en.json").then((module) => module.default),
5 | bn: () => import("./bn.json").then((module) => module.default),
6 | };
7 |
8 | export const getDictionary = async (locale) => dictionaries[locale]();
9 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/[lang]/_dictionaries/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "trending": "Trending",
3 | "new releases": "New Releases",
4 | "coming soon": "Coming Soon",
5 | "favorites": "Favorites",
6 | "watch later": "Watch Later",
7 | "details": "Details",
8 | "stream in hd": "Stream in HD",
9 | "download in hd": "Download in HD",
10 | "release date": "Release Date",
11 | "average vote": "Average Vote",
12 | "vote count": "Vote Count",
13 | "popularity": "Popularity"
14 | }
15 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/[lang]/layout.jsx:
--------------------------------------------------------------------------------
1 | import Footer from "../_components/Footer";
2 | import Header from "../_components/Header";
3 | import Sidebar from "../_components/Sidebar";
4 |
5 | const Layout = ({ children, home, movie, params: { lang } }) => {
6 | return (
7 | <>
8 |
9 |
10 |
11 |
12 | {children}
13 | {home}
14 | {movie}
15 |
16 |
17 |
18 | >
19 | );
20 | };
21 |
22 | export default Layout;
23 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/[lang]/movies/[movieId]/not-found.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import Link from "next/link";
3 | import { usePathname } from "next/navigation";
4 |
5 | export default function NotFound() {
6 | const pathName = usePathname();
7 | const movieId = pathName.split("/").pop();
8 | return (
9 |
10 |
11 | {" "}
12 | This movie with {movieId} id was not found!
13 |
14 |
15 | Return Home
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/[lang]/page.jsx:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return null;
3 | }
4 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/_components/Footer.jsx:
--------------------------------------------------------------------------------
1 | const Footer = () => {
2 | return (
3 |
10 | );
11 | };
12 |
13 | export default Footer;
14 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/api/movies/route.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 | const movies = () => import("@/data/data.json").then((res) => res.default);
3 |
4 | export async function GET() {
5 | const data = await movies();
6 | return NextResponse.json(data);
7 | }
8 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 7 - Movie DB/app/favicon.ico
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/layout.jsx:
--------------------------------------------------------------------------------
1 | import { Sora } from "next/font/google";
2 | import "./globals.css";
3 | import Header from "./_components/Header";
4 | import Footer from "./_components/Footer";
5 | import Sidebar from "./_components/Sidebar";
6 | const sora = Sora({
7 | subsets: ["latin"],
8 | weights: ["300", "400", "500", "600", "700"],
9 | });
10 | export const metadata = {
11 | title: "Movie Rental",
12 | description: "Generated by Movie Rental",
13 | };
14 |
15 | export default function RootLayout({ children }) {
16 | return (
17 |
18 |
21 | {children}
22 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/app/not-found.jsx:
--------------------------------------------------------------------------------
1 | const NotFound = () => {
2 | return This page does not exist
;
3 | };
4 |
5 | export default NotFound;
6 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/data/genres.json:
--------------------------------------------------------------------------------
1 | {
2 | "28": "Action",
3 | "12": "Adventure",
4 | "16": "Animation",
5 | "35": "Comedy",
6 | "80": "Crime",
7 | "99": "Documentary",
8 | "18": "Drama",
9 | "10751": "Family",
10 | "14": "Fantasy",
11 | "36": "History",
12 | "27": "Horror",
13 | "10402": "Music",
14 | "9648": "Mystery",
15 | "10749": "Romance",
16 | "878": "Science Fiction",
17 | "10770": "TV Movie",
18 | "53": "Thriller",
19 | "10752": "War",
20 | "37": "Western"
21 | }
22 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "paths": {
4 | "@/*": ["./*"]
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | images: {
4 | remotePatterns: [
5 | {
6 | protocol: "https",
7 | hostname: "**",
8 | },
9 | ],
10 | },
11 | };
12 |
13 | export default nextConfig;
14 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "7",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@formatjs/intl-localematcher": "^0.5.4",
13 | "negotiator": "^0.6.3",
14 | "next": "14.1.4",
15 | "react": "^18",
16 | "react-dom": "^18"
17 | },
18 | "devDependencies": {
19 | "autoprefixer": "^10.0.1",
20 | "eslint": "^8",
21 | "eslint-config-next": "14.1.4",
22 | "postcss": "^8",
23 | "tailwindcss": "^3.3.0"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/public/assets/bd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 7 - Movie DB/public/assets/bd.png
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/public/assets/cart-item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 7 - Movie DB/public/assets/cart-item.png
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/public/assets/icons/commingSoon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/public/assets/icons/moon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/public/assets/icons/newRelease.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/public/assets/icons/sun.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/public/assets/icons/trending.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/public/assets/icons/xmark.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/public/assets/movie-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 7 - Movie DB/public/assets/movie-1.png
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/public/assets/usa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 7 - Movie DB/public/assets/usa.png
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | "./pages/**/*.{js,ts,jsx,tsx,mdx}",
5 | "./components/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./app/**/*.{js,ts,jsx,tsx,mdx}",
7 | ],
8 | darkMode: "class",
9 | theme: {
10 | extend: {
11 | container: {
12 | center: true,
13 | padding: "1.25rem",
14 | },
15 | colors: {
16 | primary: "#00D991",
17 | dark: "#171923",
18 | light: "#fff",
19 | body: "#1D1E28",
20 | },
21 | },
22 | },
23 | plugins: [],
24 | };
25 |
--------------------------------------------------------------------------------
/Assignment 7 - Movie DB/utils/changeTheme.js:
--------------------------------------------------------------------------------
1 | export default function changeTheme(theme) {
2 | const html = document.documentElement;
3 | const classes = html?.classList;
4 | if (theme) {
5 | classes.remove("dark");
6 | localStorage.removeItem("theme");
7 | return false;
8 | } else {
9 | classes.add("dark");
10 | localStorage.setItem("theme", true);
11 | return true;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/.env:
--------------------------------------------------------------------------------
1 | MONGO_URI=mongodb+srv://novodip:YKTKKCnJT2et9AI4@khanakhazana.qfzgdia.mongodb.net/khanaKhazana?retryWrites=true&w=majority&appName=khanaKhazana
2 |
3 | NEXT_PUBLIC_BASE_URL=https://lws-assignment8.vercel.app
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next/core-web-vitals", "eslint:recommended"]
3 | }
4 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 |
29 | # vercel
30 | .vercel
31 |
32 | # typescript
33 | *.tsbuildinfo
34 | next-env.d.ts
35 |
36 | dist
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "paths": {
4 | "@/*": ["./src/*"]
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | images: {
4 | remotePatterns: [
5 | {
6 | protocol: 'https',
7 | hostname: 'source.unsplash.com',
8 | },
9 | {
10 | protocol: 'https',
11 | hostname: 'i.ibb.co',
12 | },
13 | ],
14 | },
15 | }
16 |
17 | export default nextConfig
18 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "khana-khazana",
3 | "type": "module",
4 | "version": "0.1.0",
5 | "private": true,
6 | "scripts": {
7 | "dev": "next dev",
8 | "build": "next build",
9 | "start": "next start",
10 | "lint": "next lint"
11 | },
12 | "dependencies": {
13 | "bcryptjs": "^2.4.3",
14 | "framer": "^2.4.1",
15 | "mongoose": "^8.3.2",
16 | "next": "^14.2.3",
17 | "plaiceholder": "^3.0.0",
18 | "react": "^18",
19 | "react-dom": "^18",
20 | "react-icons": "^5.1.0",
21 | "react-share": "^5.1.0",
22 | "react-toastify": "^10.0.5",
23 | "sharp": "^0.32.6"
24 | },
25 | "devDependencies": {
26 | "eslint": "^8",
27 | "eslint-config-next": "14.2.2",
28 | "postcss": "^8",
29 | "tailwindcss": "^3.4.1"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/public/assets/images/cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 8 - Khana Khazana/public/assets/images/cover.png
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/public/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 8 - Khana Khazana/public/assets/images/logo.png
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Learn-with-Sumit/rnext-batch-1-solutions/fd02951ebf5d9907774d254a717f4d144d64c6cd/Assignment 8 - Khana Khazana/src/app/favicon.ico
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/app/layout.js:
--------------------------------------------------------------------------------
1 | import Navbar from '@/components/Home/Navbar.jsx'
2 | import AuthProvider from '@/provider/AuthProvider.jsx'
3 | import FavoriteProvider from '@/provider/FavoriteProvider.jsx'
4 | import { Poppins } from 'next/font/google'
5 | import './globals.css'
6 |
7 | const poppins = Poppins({
8 | subsets: ['latin'],
9 | weight: ['100', '200', '300', '400', '500', '600', '700', '800', '900'],
10 | })
11 |
12 | export default async function RootLayout({ children }) {
13 | return (
14 |
15 |
16 |
17 |
18 |
19 | {children}
20 |
21 |
22 |
23 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/app/login/page.jsx:
--------------------------------------------------------------------------------
1 | import LoginForm from '@/components/Auth/LoginForm.jsx'
2 | import Link from 'next/link.js'
3 |
4 | const LoginPage = () => {
5 | return (
6 |
7 |
8 |
9 |
Sign in
10 |
11 |
Or
12 |
16 | Create New Account
17 |
18 |
19 |
20 |
21 | )
22 | }
23 | export default LoginPage
24 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/app/register/page.jsx:
--------------------------------------------------------------------------------
1 | import RegisterForm from '@/components/Auth/RegisterForm.jsx'
2 | import Link from 'next/link.js'
3 |
4 | const RegisterPage = () => {
5 | return (
6 |
7 |
8 |
9 |
Sign Up
10 |
11 |
Or
12 |
16 | Login
17 |
18 |
19 |
20 |
21 | )
22 | }
23 | export default RegisterPage
24 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/app/sitemap.js:
--------------------------------------------------------------------------------
1 | import { getRecipes } from '@/db/queries.js'
2 | import { BASE_URL } from '@/util/constants.js'
3 |
4 | export default async function sitemap() {
5 | const recipes = await getRecipes()
6 | const recipeEntriesById = recipes.map(({ id }) => ({
7 | url: `${BASE_URL}/recipe-details/${id}`,
8 | }))
9 |
10 | return [
11 | {
12 | url: `${BASE_URL}`,
13 | },
14 | ...recipeEntriesById,
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/components/Common/RecipeCardGrid.jsx:
--------------------------------------------------------------------------------
1 | import { getRecipes } from '@/db/queries.js'
2 | import RecipeCard from './RecipeCard.jsx'
3 |
4 | const RecipeCardGrid = async () => {
5 | const recipes = await getRecipes()
6 |
7 | return (
8 |
9 |
10 | {recipes?.map((recipe) => {
11 | return
12 | })}
13 |
14 |
15 | )
16 | }
17 | export default RecipeCardGrid
18 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/components/Details/RecipeSteps.jsx:
--------------------------------------------------------------------------------
1 | const RecipeSteps = ({ recipe }) => {
2 | const { steps } = recipe
3 |
4 | return (
5 |
6 |
7 |
How to Make it
8 |
9 |
10 | {steps.map((step, index) => (
11 |
17 |
Step {index + 1}
18 |
{step}
19 |
20 | ))}
21 |
22 |
23 |
24 |
25 | )
26 | }
27 | export default RecipeSteps
28 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/components/Home/RecipeContainer.jsx:
--------------------------------------------------------------------------------
1 | const RecipeContainer = ({ children }) => {
2 | return (
3 |
6 | )
7 | }
8 | export default RecipeContainer
9 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/components/Icons/CookTime.jsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { motion } from 'framer'
3 |
4 | const CookTime = () => {
5 | return (
6 |
19 |
20 |
21 |
22 |
23 |
24 | )
25 | }
26 | export default CookTime
27 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/components/Icons/Prep.jsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { motion } from 'framer'
3 | const Prep = () => {
4 | return (
5 |
19 |
20 |
21 |
22 |
23 | )
24 | }
25 | export default Prep
26 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/context/index.js:
--------------------------------------------------------------------------------
1 | import { createContext } from 'react'
2 |
3 | export const AuthContext = createContext(null)
4 | export const FavoriteContext = createContext(null)
5 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/db/conectMongo.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose'
2 |
3 | const MONGO_URI = process.env.MONGO_URI
4 | const cached = {}
5 | async function connectMongo() {
6 | if (!MONGO_URI) {
7 | throw new Error(
8 | 'Please define the MONGO_URI environment variable inside .env'
9 | )
10 | }
11 | if (cached.connection) {
12 | return cached.connection
13 | }
14 | if (!cached.promise) {
15 | const opts = {
16 | bufferCommands: false,
17 | }
18 | cached.promise = mongoose.connect(MONGO_URI, opts)
19 | }
20 | try {
21 | cached.connection = await cached.promise
22 | } catch (e) {
23 | cached.promise = undefined
24 | throw e
25 | }
26 | return cached.connection
27 | }
28 | export default connectMongo
29 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/hooks/useAuth.js:
--------------------------------------------------------------------------------
1 | import { AuthContext } from '@/context/index.js'
2 | import { useContext } from 'react'
3 |
4 | export const useAuth = () => {
5 | const { user, setUser } = useContext(AuthContext) ?? {}
6 |
7 | return { user, setUser }
8 | }
9 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/hooks/useFavorite.js:
--------------------------------------------------------------------------------
1 | import { FavoriteContext } from '@/context/index.js'
2 | import { useContext } from 'react'
3 |
4 | export const useFavorites = () => {
5 | const { favorites, setFavorites } = useContext(FavoriteContext) ?? {}
6 |
7 | return { favorites, setFavorites }
8 | }
9 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/hooks/useInputTypeConverter.js:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 |
3 | export const PASSWORD = 'password'
4 | export const TEXT = 'text'
5 |
6 | const useInputTypeConverter = () => {
7 | const [inputType, setInputType] = useState(PASSWORD)
8 | const makeInputTypeText = () => setInputType(TEXT)
9 | const makeInputTypePassword = () => setInputType(PASSWORD)
10 |
11 | return { inputType, makeInputTypePassword, makeInputTypeText }
12 | }
13 | export default useInputTypeConverter
14 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/middleware.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 |
3 | export function middleware(request) {
4 | const isLoggedIn = request.cookies.has('user')
5 | // if user is logged in redirect to the home page
6 | if (isLoggedIn) {
7 | return NextResponse.redirect(new URL('/', request.url))
8 | }
9 | }
10 |
11 | export const config = {
12 | matcher: '/login',
13 | }
14 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/models/User.js:
--------------------------------------------------------------------------------
1 | import { model, models, Schema } from 'mongoose'
2 |
3 | const schema = new Schema({
4 | firstName: {
5 | required: true,
6 | type: String,
7 | },
8 | lastName: {
9 | required: true,
10 | type: String,
11 | },
12 | email: {
13 | required: true,
14 | type: String,
15 | unique: true,
16 | },
17 | password: {
18 | required: true,
19 | type: String,
20 | },
21 | favorites: {
22 | type: [String],
23 | default: [],
24 | },
25 | })
26 |
27 | export const UserModel = models.users || model('users', schema)
28 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/provider/AuthProvider.jsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { AuthContext } from '@/context/index.js'
3 | import { useState } from 'react'
4 |
5 | const AuthProvider = ({ children }) => {
6 | const [user, setUser] = useState(null)
7 |
8 | return (
9 |
10 | {children}
11 |
12 | )
13 | }
14 | export default AuthProvider
15 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/provider/FavoriteProvider.jsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { FavoriteContext } from '@/context/index.js'
3 | import { useState } from 'react'
4 |
5 | const FavoriteProvider = ({ children }) => {
6 | const [favorites, setFavorites] = useState([])
7 |
8 | return (
9 |
10 | {children}
11 |
12 | )
13 | }
14 | export default FavoriteProvider
15 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/util/checkValidMongooseId.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose'
2 |
3 | const checkValidMongooseId = (id) => mongoose.Types.ObjectId.isValid(id)
4 |
5 | export default checkValidMongooseId
6 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/util/getRandomInteger.js:
--------------------------------------------------------------------------------
1 | export default function getRndInteger(min, max) {
2 | return Math.floor(Math.random() * (max - min)) + min
3 | }
4 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/src/util/getUniqueCategories.js:
--------------------------------------------------------------------------------
1 | export const getUniqueCategories = (recipes) => {
2 | const categories = []
3 | recipes.forEach((recipe) => {
4 | if (!categories.includes(recipe.category)) {
5 | categories.push(recipe.category)
6 | }
7 | })
8 | return categories
9 | }
10 |
--------------------------------------------------------------------------------
/Assignment 8 - Khana Khazana/todo.md:
--------------------------------------------------------------------------------
1 | RECHECK
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
25 |
--------------------------------------------------------------------------------