Upgraded to next v15 and eslint to v9
This commit is contained in:
parent
65fc690787
commit
1f1b128b24
.eslintrc.jsoneslint.config.mjsnext.config.tspackage-lock.jsonpackage.jsontsconfig.json
src
app
components
hooks
providers
@ -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
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
980
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
17
package.json
17
package.json
@ -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"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user