Upgraded to next v15 and eslint to v9

This commit is contained in:
Amritanshu Agrawal 2024-10-23 12:18:24 +05:30
parent 65fc690787
commit 1f1b128b24
16 changed files with 622 additions and 570 deletions

@ -1,48 +0,0 @@
{
"extends": [
"prettier",
"next/core-web-vitals",
"next/typescript",
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:@next/next/recommended"
],
"plugins": ["prettier", "eslint-plugin-import", "@typescript-eslint"],
"rules": {
"lines-between-class-members": [
"error",
"always",
{
"exceptAfterSingleLine": true
}
],
"import/order": [
"error",
{
"alphabetize": {
"order": "asc",
"caseInsensitive": true
},
"newlines-between": "always"
}
], // Optionally, disable the default ESLint sort rule if you're using it
"no-duplicate-imports": "error",
"prettier/prettier": "error",
"react/no-unescaped-entities": "error",
"react/react-in-jsx-scope": "off",
"react/prop-types": [2, { "ignore": ["className", "position"] }],
"import/no-deprecated": "warn",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
},
"env": {
"browser": true,
"node": true
},
"settings": {
"react": {
"version": "detect"
}
}
}

85
eslint.config.mjs Normal file

@ -0,0 +1,85 @@
import js from '@eslint/js';
import nextPlugin from '@next/eslint-plugin-next';
import pluginImport from 'eslint-plugin-import';
import configPrettier from 'eslint-plugin-prettier/recommended';
import reactPlugin from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import tseslint from 'typescript-eslint';
export default [
configPrettier,
js.configs.recommended,
...tseslint.configs.recommended,
...tseslint.configs.stylistic,
reactPlugin.configs.flat.recommended, // This is not a plugin object, but a shareable config object
reactPlugin.configs.flat['jsx-runtime'], // Add this if you are using React 17+
{
plugins: {
'react-hooks': reactHooks,
},
rules: reactHooks.configs.recommended.rules,
},
{
plugins: {
'@next/next': nextPlugin,
},
rules: nextPlugin.configs.recommended.rules,
},
{
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
plugins: {
import: pluginImport,
},
rules: {
'import/order': [
'error',
{
alphabetize: {
order: 'asc',
caseInsensitive: true,
},
'newlines-between': 'always',
},
],
'import/no-deprecated': 'warn',
},
},
{
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
settings: {
react: {
version: 'detect',
},
},
rules: {
'no-duplicate-imports': 'error',
'@/lines-between-class-members': [
'error',
'always',
{
exceptAfterSingleLine: true,
},
],
'prettier/prettier': 'error',
'react/no-unescaped-entities': 'error',
'react/react-in-jsx-scope': 'off',
'react/prop-types': [
2,
{
ignore: ['className', 'position'],
},
],
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
},
],
},
},
];

@ -1,5 +1,6 @@
/** @type {import('next').NextConfig} */ import type { NextConfig } from 'next';
const nextConfig = {
const nextConfig: NextConfig = {
output: 'standalone', output: 'standalone',
images: { images: {
remotePatterns: [ remotePatterns: [

980
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -31,9 +31,9 @@
"clsx": "^2.1.1", "clsx": "^2.1.1",
"lucide-react": "^0.447.0", "lucide-react": "^0.447.0",
"medusa-react": "^9.0.18", "medusa-react": "^9.0.18",
"next": "14.2.16", "next": "^15.0.1-canary.3",
"react": "18.3.1", "react": "^19.0.0-rc-45804af1-20241021",
"react-dom": "18.3.1", "react-dom": "^19.0.0-rc-45804af1-20241021",
"react-icons": "^5.3.0", "react-icons": "^5.3.0",
"sharp": "^0.33.5", "sharp": "^0.33.5",
"swiper": "^11.1.14", "swiper": "^11.1.14",
@ -42,20 +42,25 @@
"tailwindcss-animate": "^1.0.7" "tailwindcss-animate": "^1.0.7"
}, },
"devDependencies": { "devDependencies": {
"@next/eslint-plugin-next": "^15.0.0-rc.1",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "18.3.12", "@types/react": "18.3.12",
"@types/react-dom": "18.3.1", "@types/react-dom": "18.3.1",
"@typescript-eslint/eslint-plugin": "^8.8.1", "@typescript-eslint/eslint-plugin": "^8.8.1",
"@typescript-eslint/parser": "^8.8.1", "@typescript-eslint/parser": "^8.8.1",
"eslint": "^8", "eslint": "^9.13.0",
"eslint-config-next": "14.2.16", "eslint-config-next": "^15.0.0-rc.1",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.31.0", "eslint-plugin-import": "^2.31.0",
"eslint-plugin-next": "^0.0.0",
"eslint-plugin-prettier": "^5.2.1", "eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.0.0",
"postcss": "^8", "postcss": "^8",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",
"typescript": "^5" "typescript": "^5",
"typescript-eslint": "^8.11.0"
}, },
"overrides": { "overrides": {
"@types/react": "18.3.12", "@types/react": "18.3.12",

@ -1,12 +1,12 @@
'use server'; 'use server';
export type ContactFormState = { export interface ContactFormState {
name: string; name: string;
phone: string; phone: string;
email: string; email: string;
message: string; message: string;
status: string; status: string;
}; }
export async function saveContactForm(state: ContactFormState, formData: FormData): Promise<ContactFormState> { export async function saveContactForm(state: ContactFormState, formData: FormData): Promise<ContactFormState> {
const url = const url =

@ -100,6 +100,6 @@ export default async function ProductPage(props: ProductPageProps) {
return ( return (
// Render the client component and pass necessary props // Render the client component and pass necessary props
(<ProductDetails product={product} relatedProducts={products} />) <ProductDetails product={product} relatedProducts={products} />
); );
} }

@ -1,15 +1,13 @@
import React from 'react';
import styles from './PillButton.module.css'; import styles from './PillButton.module.css';
type PillButtonProps = { interface PillButtonProps {
text: string; // text prop is now required text: string; // text prop is now required
className?: string; className?: string;
// Additional props if needed // Additional props if needed
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any; [key: string]: any;
onClick?: () => void; // onClick is optional onClick?: () => void; // onClick is optional
}; }
export function PillButton({ text, className = '', onClick, ...props }: PillButtonProps) { export function PillButton({ text, className = '', onClick, ...props }: PillButtonProps) {
return ( return (

@ -1,7 +1,6 @@
// src/components/AnimatedImage.tsx // src/components/AnimatedImage.tsx
'use client'; 'use client';
import Image, { StaticImageData } from 'next/image'; import Image, { StaticImageData } from 'next/image';
import React from 'react';
import useInView from '@/hooks/useInView'; import useInView from '@/hooks/useInView';

@ -1,7 +1,7 @@
'use client'; 'use client';
import Image from 'next/image'; import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import React, { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { FiSearch, FiUser } from 'react-icons/fi'; import { FiSearch, FiUser } from 'react-icons/fi';
import { HiShoppingBag } from 'react-icons/hi2'; import { HiShoppingBag } from 'react-icons/hi2';

@ -1,12 +1,11 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
// eslint-disable-next-line no-unused-vars
type Callback = (entry: IntersectionObserverEntry) => void; type Callback = (entry: IntersectionObserverEntry) => void;
class IntersectionObserverManager { class IntersectionObserverManager {
private observer: IntersectionObserver; private observer: IntersectionObserver;
private callbacks: Map<Element, Callback>; private callbacks: Map<Element, Callback>;
// eslint-disable-next-line no-undef
constructor(options: IntersectionObserverInit) { constructor(options: IntersectionObserverInit) {
this.callbacks = new Map(); this.callbacks = new Map();
@ -44,7 +43,6 @@ class IntersectionObserverManager {
let manager: IntersectionObserverManager | null = null; let manager: IntersectionObserverManager | null = null;
// eslint-disable-next-line no-undef
const getObserverManager = (options: IntersectionObserverInit) => { const getObserverManager = (options: IntersectionObserverInit) => {
if (!manager) { if (!manager) {
manager = new IntersectionObserverManager(options); manager = new IntersectionObserverManager(options);
@ -52,10 +50,7 @@ const getObserverManager = (options: IntersectionObserverInit) => {
return manager; return manager;
}; };
export const useSharedIntersectionObserver = ( export const useSharedIntersectionObserver = (options: IntersectionObserverInit) => {
// eslint-disable-next-line no-undef
options: IntersectionObserverInit,
) => {
useEffect(() => { useEffect(() => {
return () => { return () => {
// Cleanup logic if needed // Cleanup logic if needed
@ -67,8 +62,11 @@ export const useSharedIntersectionObserver = (
if (typeof window === 'undefined') { if (typeof window === 'undefined') {
// Return a dummy manager for SSR // Return a dummy manager for SSR
return { return {
// eslint-disable-next-line @typescript-eslint/no-empty-function
observe: () => {}, observe: () => {},
// eslint-disable-next-line @typescript-eslint/no-empty-function
unobserve: () => {}, unobserve: () => {},
// eslint-disable-next-line @typescript-eslint/no-empty-function
disconnect: () => {}, disconnect: () => {},
} as unknown as IntersectionObserverManager; } as unknown as IntersectionObserverManager;
} }

@ -3,7 +3,6 @@ import { RefObject, useEffect, useRef, useState } from 'react';
import { useSharedIntersectionObserver } from './shared-intersection-observer'; import { useSharedIntersectionObserver } from './shared-intersection-observer';
// eslint-disable-next-line no-undef
interface UseInViewOptions extends IntersectionObserverInit { interface UseInViewOptions extends IntersectionObserverInit {
triggerOnce?: boolean; triggerOnce?: boolean;
} }

@ -5,20 +5,20 @@ import React, { createContext, useContext, useEffect, useState } from 'react';
import { useRegion } from './region'; import { useRegion } from './region';
type CartContextType = { interface CartContextType {
cart?: HttpTypes.StoreCart; cart?: HttpTypes.StoreCart;
setCart: React.Dispatch<React.SetStateAction<HttpTypes.StoreCart | undefined>>; setCart: React.Dispatch<React.SetStateAction<HttpTypes.StoreCart | undefined>>;
addToCart: (variant_id: string, quantity: number) => void; addToCart: (variant_id: string, quantity: number) => void;
updateQuantity: (item_id: string, quantity: number) => void; updateQuantity: (item_id: string, quantity: number) => void;
removeItem: (item_id: string) => void; removeItem: (item_id: string) => void;
refreshCart: () => void; refreshCart: () => void;
}; }
const CartContext = createContext<CartContextType | null>(null); const CartContext = createContext<CartContextType | null>(null);
type CartProviderProps = { interface CartProviderProps {
children: React.ReactNode; children: React.ReactNode;
}; }
export const CartProvider = ({ children }: CartProviderProps) => { export const CartProvider = ({ children }: CartProviderProps) => {
const [cart, setCart] = useState<HttpTypes.StoreCart>(); const [cart, setCart] = useState<HttpTypes.StoreCart>();
@ -68,7 +68,7 @@ export const CartProvider = ({ children }: CartProviderProps) => {
setCart(undefined); setCart(undefined);
}; };
function addToCart(variant_id: string, quantity: number = 1) { function addToCart(variant_id: string, quantity = 1) {
if (!cart) { if (!cart) {
return; return;
} }

@ -3,18 +3,18 @@
import { HttpTypes } from '@medusajs/types'; import { HttpTypes } from '@medusajs/types';
import React, { createContext, useContext, useEffect, useState } from 'react'; import React, { createContext, useContext, useEffect, useState } from 'react';
type CustomerContextType = { interface CustomerContextType {
customer: HttpTypes.StoreCustomer | undefined; customer: HttpTypes.StoreCustomer | undefined;
register: (firstName: string, lastName: string, email: string, password: string) => Promise<void>; register: (firstName: string, lastName: string, email: string, password: string) => Promise<void>;
login: (email: string, password: string) => Promise<void>; login: (email: string, password: string) => Promise<void>;
logout: () => void; logout: () => void;
}; }
const CustomerContext = createContext<CustomerContextType | null>(null); const CustomerContext = createContext<CustomerContextType | null>(null);
type CustomerProviderProps = { interface CustomerProviderProps {
children: React.ReactNode; children: React.ReactNode;
}; }
export const CustomerProvider = ({ children }: CustomerProviderProps) => { export const CustomerProvider = ({ children }: CustomerProviderProps) => {
const [customer, setCustomer] = useState<HttpTypes.StoreCustomer | undefined>(); const [customer, setCustomer] = useState<HttpTypes.StoreCustomer | undefined>();

@ -3,16 +3,16 @@
import { HttpTypes } from '@medusajs/types'; import { HttpTypes } from '@medusajs/types';
import React, { createContext, useContext, useEffect, useState } from 'react'; import React, { createContext, useContext, useEffect, useState } from 'react';
type RegionContextType = { interface RegionContextType {
region?: HttpTypes.StoreRegion; region?: HttpTypes.StoreRegion;
setRegion: React.Dispatch<React.SetStateAction<HttpTypes.StoreRegion | undefined>>; setRegion: React.Dispatch<React.SetStateAction<HttpTypes.StoreRegion | undefined>>;
}; }
const RegionContext = createContext<RegionContextType | null>(null); const RegionContext = createContext<RegionContextType | null>(null);
type RegionProviderProps = { interface RegionProviderProps {
children: React.ReactNode; children: React.ReactNode;
}; }
export const RegionProvider = ({ children }: RegionProviderProps) => { export const RegionProvider = ({ children }: RegionProviderProps) => {
const [region, setRegion] = useState<HttpTypes.StoreRegion>(); const [region, setRegion] = useState<HttpTypes.StoreRegion>();

@ -19,7 +19,8 @@
], ],
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": ["./src/*"]
} },
"target": "ES2017"
}, },
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"] "exclude": ["node_modules"]