diff --git a/apps/st/.gitignore b/apps/st/.gitignore index b63718b61..f06d9d40b 100644 --- a/apps/st/.gitignore +++ b/apps/st/.gitignore @@ -38,4 +38,5 @@ yarn-error.log* next-env.d.ts .env* -!.env.example \ No newline at end of file +!.env.example +*.md \ No newline at end of file diff --git a/apps/st/.prettierrc b/apps/st/.prettierrc index b4bfed357..a7963dac2 100644 --- a/apps/st/.prettierrc +++ b/apps/st/.prettierrc @@ -1,3 +1,4 @@ { - "plugins": ["prettier-plugin-tailwindcss"] + "plugins": ["prettier-plugin-tailwindcss"], + "tabWidth": 4 } diff --git a/apps/st/package.json b/apps/st/package.json index a501dde6a..cd951af0d 100644 --- a/apps/st/package.json +++ b/apps/st/package.json @@ -12,7 +12,7 @@ "@common/assets": "workspace:*", "@common/components": "workspace:*", "@common/config": "workspace:*", - "@rsone/components": "workspace:*", + "@faker-js/faker": "^9.9.0", "@fontsource-variable/noto-sans-kr": "^5.2.5", "@frontend-opensource/use-react-hooks": "^1.1.4", "@fullcalendar/core": "^6.1.17", @@ -26,6 +26,7 @@ "@radix-ui/react-label": "^2.1.2", "@radix-ui/react-slot": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.8", + "@rsone/components": "workspace:*", "@tanstack/react-query": "^5.67.1", "@tanstack/react-query-devtools": "^5.75.5", "@tanstack/react-table": "^8.21.2", diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index cdf0e286d..520a6c47f 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -155,16 +155,16 @@ function updateHeaderSortIndicator( function createOnSortingHandler( columns: { fieldName?: string; name: string; mergeCells?: boolean; sortdisable?: boolean; valueType?: ValueType }[], setRowData: React.Dispatch[]>>, - sortDirRef: React.MutableRefObject>, - originalRowsRef: React.MutableRefObject[]>> + sortDirRef: { current: Record }, + originalRowsRef: { current: Record[]> } ) { const fieldNames = [...new Set(columns.map((c) => c.fieldName).filter((x): x is string => typeof x === "string"))]; // mergeCells: true인 컬럼 찾기 (시군구 등) - 그룹 필드로 사용 // 시군구를 우선으로 찾고, 없으면 첫 번째 mergeCells 컬럼 사용 const mergeCellCols = columns.filter((c) => c.mergeCells === true && c.fieldName); - const mergeCellCol = mergeCellCols.find((c) => c.fieldName === '시군구') || mergeCellCols[0]; + const mergeCellCol = mergeCellCols.find((c) => c.fieldName === 'gugun') || mergeCellCols[0]; const groupField = mergeCellCol?.fieldName || null; - const orderByField = '구분'; // 고정값 또는 설정 가능하게 할 수 있음 + const orderByField = 'rgnNm'; // 고정값 또는 설정 가능하게 할 수 있음 const hasMergeCells = mergeCellCols.length > 0; return function onSorting(g: unknown, fields: unknown[], _directions: unknown[]) { diff --git a/apps/st/src/components/module/SearchForm.tsx b/apps/st/src/components/module/SearchForm.tsx index 0b50ecf89..91d823ed6 100644 --- a/apps/st/src/components/module/SearchForm.tsx +++ b/apps/st/src/components/module/SearchForm.tsx @@ -118,6 +118,18 @@ const SearchForm = (props: SearchFormProps = {}) => { })); }; + const handleSggChange = (value: string) => { + const selectedBsnm = value === 'ALL' + ? (sidoList?.data.sidoList.find((v) => v.sido === values.sido)?.bsnmCd || '') + : (sggList?.data?.find((v) => v.gugun === value)?.bsnmCd || ''); + + setValues((prev) => ({ + ...prev, + gugun: value, + bsnmCd: selectedBsnm, + })); + }; + useEffect(() => { props.onValuesChange?.(values); }, [values]); @@ -151,7 +163,7 @@ const SearchForm = (props: SearchFormProps = {}) => { - diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 950f43988..036af18b8 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,5 +1,6 @@ -import { useState } from "react"; -import { DataGrid } from "@rsone/components"; +import { useState, useMemo } from "react"; +// import { DataGrid } from "@rsone/components"; +import DataGrid from "@/components/module/DataGrid"; import SearchForm from "@/components/module/SearchForm"; import SaveButton from "@/components/button/SaveButton"; import ApproveButton from "@/components/button/ApproveButton"; @@ -12,12 +13,27 @@ import { sewerageSupplyRateReviewApi } from "@/entities/statistics/api/statistic import type { SewerageSupplyRateReviewItem } from "@/entities/statistics/model/statistics-management-interface"; import { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateRvwColumn"; import type { SearchFormValues } from "@/components/type/SearchForm.type"; +import { toGridRows } from "@/components/util/grid/gridFunction"; // 하수도 통계 검토 01. 하수도 보급률 const SeweragePenetrationRateRvw = () => { const { setMessage: alert } = useAlertStore((state) => state); - -const [rowData, setRowData] = useState([]); + + const columnInfo = useMemo(() => { + const { columns, columnLayout, fixedColumns, rowStartNum } = SeweragePenetrationRateInfoList; + return { + columnLayout, + fixedColumns, + rowStartNum, + columns: columns.map((col) => ({ + ...col, + editable: false as const, + styleName: col.styleName ?? ("rg-cell-readonly" as const), + })), + }; + }, []); + + const [rowData, setRowData] = useState([]); const [isLoading, setIsLoading] = useState(false); const handleReset = () => { @@ -29,10 +45,10 @@ const [rowData, setRowData] = useState([]); setIsLoading(true); const response = await sewerageSupplyRateReviewApi.getSewerageSupplyRateReviewList({ - sido: "경기도", - gugun: "과천시", - yr: 2024, - bsnmCd: "4129000000" + sido: values.sido, + gugun: values.gugun === 'ALL' ? '' : values.gugun, + bsnmCd: values.bsnmCd, + yr: values.year, }); console.log("네트워크 응답 전체:", response); @@ -42,14 +58,13 @@ const [rowData, setRowData] = useState([]); console.log("받아온 리스트:", rawList); - const convertedData: SewerageSupplyRateReviewItem[] = rawList.map((item) => ({ ...item, speclCntrplnAr: !item.speclCntrplnAr ? '해당없음' : item.speclCntrplnAr, })); - setRowData(convertedData); + setRowData(toGridRows(convertedData)); } else { setRowData([]); @@ -80,12 +95,12 @@ const [rowData, setRowData] = useState([]); ); diff --git a/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx index 6e9cc3a6e..1d5dfd169 100644 --- a/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx +++ b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx @@ -1,11 +1,482 @@ +"use client"; + +import { useState } from "react"; +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; +import { + Button, + Input, + Label, + Select, + SelectTrigger, + SelectContent, + SelectItem, + SelectValue, + Checkbox, +} from "@common/components"; +import { verificationHistoryColumnInfo } from "@/entities/statistics/model/verification-history-column"; +import { verificationHistoryMockData } from "@/entities/statistics/model/verification-history-mock"; + +interface VerificationFormValues { + mu: string; + percentile: string; + a: string; + c: string; + verificationYear: string; + checkboxOptions: { + sidoDistribution: boolean; + countyDistribution: boolean; + countyDistributionUserManagement: boolean; + lowerDistribution: boolean; + sidoServiceAvailability: boolean; + individualService: boolean; + legalServiceUsage: boolean; + excessUse: boolean; + lowerOrgStatistics: boolean; + studentStatistics: boolean; + developmentStatistics: boolean; + lowerManagementEnterprise: boolean; + }; +} const ManagementVerificationRule = () => { + const [verificationHistoryRowData, setVerificationHistoryRowData] = + useState[]>( + verificationHistoryMockData, + ); + + const [formValues, setFormValues] = useState({ + mu: "0", + percentile: "0", + a: "0", + c: "0", + verificationYear: "2025", + checkboxOptions: { + sidoDistribution: false, + countyDistribution: false, + countyDistributionUserManagement: false, + lowerDistribution: false, + sidoServiceAvailability: false, + individualService: false, + legalServiceUsage: false, + excessUse: false, + lowerOrgStatistics: false, + studentStatistics: false, + developmentStatistics: false, + lowerManagementEnterprise: false, + }, + }); + + const handleCheckboxChange = ( + key: keyof VerificationFormValues["checkboxOptions"], + ) => { + setFormValues((prev) => ({ + ...prev, + checkboxOptions: { + ...prev.checkboxOptions, + [key]: !prev.checkboxOptions[key], + }, + })); + }; + + const handleInputChange = ( + key: keyof Omit, + value: string, + ) => { + setFormValues((prev) => ({ + ...prev, + [key]: value, + })); + }; + + const handleSubmit = () => { + console.log("검증 실행:", formValues); + }; + + const handleReset = () => { + console.log("초기화"); + }; + return ( - <> - - +
+
+ {/* 통계 검증 섹션 */} +
+

+ 통계 검증 +

+ +
+ {/* 왼쪽: 검증 변수 */} +
+

+ 검증 변수 +

+ +
+
+ + + handleInputChange( + "mu", + e.target.value, + ) + } + className="flex-1" + /> +
+ +
+ + + handleInputChange( + "percentile", + e.target.value, + ) + } + className="flex-1" + /> +
+ +
+ + + handleInputChange( + "a", + e.target.value, + ) + } + className="flex-1" + /> +
+ +
+ + + handleInputChange( + "c", + e.target.value, + ) + } + className="flex-1" + /> +
+ +
+ + +
+
+
+ + {/* 오른쪽: 검증 대상 */} +
+

+ 검증 대상 +

+ +
+
+
+ + handleCheckboxChange( + "sidoDistribution", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "countyDistribution", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "countyDistributionUserManagement", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "lowerDistribution", + ) + } + /> + +
+
+ +
+
+ + handleCheckboxChange( + "sidoServiceAvailability", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "individualService", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "sidoServiceAvailability", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "individualService", + ) + } + /> + +
+
+ +
+
+ + handleCheckboxChange( + "lowerOrgStatistics", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "studentStatistics", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "lowerOrgStatistics", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "studentStatistics", + ) + } + /> + +
+
+ +
+
+ + handleCheckboxChange( + "lowerManagementEnterprise", + ) + } + /> + +
+
+
+
+
+
+ + {/* 버튼 */} +
+ + +
+ + {/* 검증 이력 섹션 */} +
+

+ 검증 이력 +

+ +
+
+
); }; -export default ManagementVerificationRule; \ No newline at end of file +export default ManagementVerificationRule; diff --git a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts index e2cb0ca12..182d2d50d 100644 --- a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts +++ b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts @@ -13,7 +13,7 @@ export const SeweragePenetrationRateInpColumn = { // 수계 및 권역 { name: 'rvbsn', fieldName: 'rvbsn', header: { text: '수계' }, editable: false }, - { name: 'bstrm', fieldName: 'bstrm', header: { text: '지류' }, editable: false }, + { name: 'bstrm', fieldName: 'bstrm', header: { text: '지류' } }, // 수계영향권별분류 { name: 'mdbsn', fieldName: 'mdbsn', header: { text: '세부단위유역' }, editable: false }, diff --git a/apps/st/src/components/util/grid/footerSummary.ts b/apps/st/src/components/util/grid/footerSummary.ts index cbf60db84..39825a0dd 100644 --- a/apps/st/src/components/util/grid/footerSummary.ts +++ b/apps/st/src/components/util/grid/footerSummary.ts @@ -48,8 +48,8 @@ export const getFooterAvgSummary = (grid: GridView, column: DataColumn) => { return Math.floor(avg * 10) / 10; } -// "구분" 필드의 고유값들을 찾는 함수 (첫 번째, 두 번째) -const getDivisionValues = (grid: GridView, divisionFieldName: string = '구분'): string[] => { +// 구분 필드의 고유값들을 찾는 함수 (첫 번째, 두 번째). 기본 필드명 'rgnNm' +const getDivisionValues = (grid: GridView, divisionFieldName: string = 'rgnNm'): string[] => { const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); const uniqueValues = new Set(); @@ -65,13 +65,13 @@ const getDivisionValues = (grid: GridView, divisionFieldName: string = '구분') return Array.from(uniqueValues); }; -// "구분" 필드 값에 따라 필터링하여 합계 계산하는 함수 +// 구분 필드 값에 따라 필터링하여 합계 계산하는 함수. 기본 필드명 'rgnNm' // divisionIndex: 0 = 첫 번째 고유값, 1 = 두 번째 고유값 export const getFooterSummaryByDivision = ( - grid: GridView, - column: DataColumn, + grid: GridView, + column: DataColumn, divisionIndex: number, - divisionFieldName: string = '구분' + divisionFieldName: string = 'rgnNm' ) => { const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); @@ -107,13 +107,13 @@ export const getFooterSummaryByDivision = ( return sum; }; -// "구분" 필드 값에 따라 필터링하여 평균 계산하는 함수 +// 구분 필드 값에 따라 필터링하여 평균 계산하는 함수. 기본 필드명 'rgnNm' // divisionIndex: 0 = 첫 번째 고유값, 1 = 두 번째 고유값 export const getFooterAvgSummaryByDivision = ( - grid: GridView, - column: DataColumn, + grid: GridView, + column: DataColumn, divisionIndex: number, - divisionFieldName: string = '구분' + divisionFieldName: string = 'rgnNm' ) => { const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); @@ -173,67 +173,51 @@ const createAvgFooter = (format: string) => ({ }, }); -// "구분" 값에 따라 필터링하는 Footer 배열 생성 함수 (2줄) -const createSumFooterArrayByDivision = (format: string) => [ +// 구분 값에 따라 필터링하는 Footer 배열 생성 함수 (2줄). 기본 필드명 'rgnNm' +const createSumFooterArrayByDivision = (format: string, divisionFieldName: string = 'rgnNm') => [ { numberFormat: format, valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: unknown, + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, value: number | string | undefined - ) => { - // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) - // footerIndex를 divisionIndex로 사용 - return getFooterSummaryByDivision(grid, column, footerIndex); - }, + ) => getFooterSummaryByDivision(grid, column, footerIndex, divisionFieldName), }, { numberFormat: format, valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: unknown, + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, value: number | string | undefined - ) => { - // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) - // footerIndex를 divisionIndex로 사용 - return getFooterSummaryByDivision(grid, column, footerIndex); - }, + ) => getFooterSummaryByDivision(grid, column, footerIndex, divisionFieldName), }, ]; -// "구분" 값에 따라 필터링하는 평균 Footer 배열 생성 함수 (2줄) -const createAvgFooterArrayByDivision = (format: string) => [ +// 구분 값에 따라 필터링하는 평균 Footer 배열 생성 함수 (2줄). 기본 필드명 'rgnNm' +const createAvgFooterArrayByDivision = (format: string, divisionFieldName: string = 'rgnNm') => [ { numberFormat: format, valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: unknown, + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, value: number | string | undefined - ) => { - // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) - // footerIndex를 divisionIndex로 사용 - return getFooterAvgSummaryByDivision(grid, column, footerIndex); - }, + ) => getFooterAvgSummaryByDivision(grid, column, footerIndex, divisionFieldName), }, { numberFormat: format, valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: unknown, + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, value: number | string | undefined - ) => { - // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) - // footerIndex를 divisionIndex로 사용 - return getFooterAvgSummaryByDivision(grid, column, footerIndex); - }, + ) => getFooterAvgSummaryByDivision(grid, column, footerIndex, divisionFieldName), }, ]; diff --git a/apps/st/src/components/util/grid/gridFunction.ts b/apps/st/src/components/util/grid/gridFunction.ts index 173a7ac6d..28755a7f8 100644 --- a/apps/st/src/components/util/grid/gridFunction.ts +++ b/apps/st/src/components/util/grid/gridFunction.ts @@ -1,10 +1,15 @@ -import type { SewerageSupplyRateItem } from "@/entities/statistics/model/statistics-input-interface"; - -export function toGridRows(items: SewerageSupplyRateItem[]): Record[] { +/** + * 객체 배열을 그리드 row 형식으로 변환 (null/undefined → ""). + * 어떤 엔티티 타입이든 공통 사용 가능. + */ +export function toGridRows( + items: T[] +): Record[] { return items.map((item) => { const row: Record = {}; for (const [key, value] of Object.entries(item)) { - row[key] = value === null || value === undefined ? "" : value; + row[key] = + value === null || value === undefined ? "" : (value as string | number); } return row; }); diff --git a/apps/st/src/entities/statistics/model/statistics-interface.ts b/apps/st/src/entities/statistics/model/statistics-interface.ts index 5ff8a5ed7..b909eba92 100644 --- a/apps/st/src/entities/statistics/model/statistics-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-interface.ts @@ -4,6 +4,11 @@ export interface Sido { bsnmCd: string; } +export interface SearchCondition { + yearList: string[]; + sidoList: Sido[]; +} + export interface Sgg { adstDstrCd: string; gugun: string; @@ -17,6 +22,6 @@ export interface ApiResponse { } export interface StatisticsService { - getSidoList(): Promise>; + getSidoList(): Promise>; getSggList(sidoName: string): Promise>; } \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/statistics-management-interface.ts b/apps/st/src/entities/statistics/model/statistics-management-interface.ts index 858859b28..b8078a186 100644 --- a/apps/st/src/entities/statistics/model/statistics-management-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-management-interface.ts @@ -83,7 +83,7 @@ export type SewerageSupplyRateReviewApiResponse = ApiResponse[] { + faker.seed(42); + return Array.from({ length: count }, () => { + const executedAt = faker.date.recent({ days: 90 }); + const durationMinutes = faker.number.int({ min: 1, max: 120 }); + const endedAt = new Date( + executedAt.getTime() + durationMinutes * 60 * 1000, + ); + const status = faker.helpers.arrayElement(PROGRESS_STATUSES); + const normalCount = faker.number.int({ min: 0, max: 500 }); + const excludedCount = faker.number.int({ min: 0, max: 50 }); + const abnormalCount = faker.number.int({ min: 0, max: 30 }); + const item: VerificationHistoryItem = { + executedAt: formatDateTime(executedAt), + progressStatus: status, + endedAt: formatDateTime(endedAt), + verificationYear: String(executedAt.getFullYear()), + mu: faker.number.float({ min: 0, max: 1, fractionDigits: 3 }), + percentile: faker.number.float({ + min: 0, + max: 100, + fractionDigits: 2, + }), + a: faker.number.float({ min: 0, max: 10, fractionDigits: 3 }), + c: faker.number.float({ min: 0, max: 10, fractionDigits: 3 }), + target: faker.helpers.arrayElement(VERIFICATION_TARGETS), + normalCount, + excludedCount, + abnormalCount, + }; + return { ...item } as Record; + }); +} + +/** 검증 이력 기본 목데이터 (10건) */ +export const verificationHistoryMockData = createVerificationHistoryMock(10); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab7fd8d4a..2a3d2ab29 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -170,10 +170,10 @@ importers: version: 5.28.5 eslint: specifier: ^9.0.0 - version: 9.39.2(jiti@1.21.7) + version: 9.39.2(jiti@2.6.1) eslint-config-next: specifier: 15.4.0 - version: 15.4.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + version: 15.4.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) postcss: specifier: ^8.4.49 version: 8.5.6 @@ -897,6 +897,9 @@ importers: '@common/config': specifier: workspace:* version: link:../../packages/common/config + '@faker-js/faker': + specifier: ^9.9.0 + version: 9.9.0 '@fontsource-variable/noto-sans-kr': specifier: ^5.2.5 version: 5.2.9 @@ -1035,10 +1038,10 @@ importers: version: 5.28.5 eslint: specifier: ^9 - version: 9.39.2(jiti@2.6.1) + version: 9.39.2(jiti@1.21.7) eslint-config-next: specifier: 15.1.7 - version: 15.1.7(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 15.1.7(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) postcss: specifier: ^8 version: 8.5.6 @@ -5036,6 +5039,7 @@ packages: glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true globals@14.0.0: @@ -10316,6 +10320,26 @@ snapshots: optionalDependencies: source-map: 0.7.6 + eslint-config-next@15.1.7(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): + dependencies: + '@next/eslint-plugin-next': 15.1.7 + '@rushstack/eslint-patch': 1.15.0 + '@typescript-eslint/eslint-plugin': 8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.39.2(jiti@1.21.7) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-react: 7.37.5(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.39.2(jiti@1.21.7)) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + eslint-config-next@15.1.7(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: '@next/eslint-plugin-next': 15.1.7 @@ -10336,26 +10360,6 @@ snapshots: - eslint-plugin-import-x - supports-color - eslint-config-next@15.4.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): - dependencies: - '@next/eslint-plugin-next': 15.4.0 - '@rushstack/eslint-patch': 1.15.0 - '@typescript-eslint/eslint-plugin': 8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/parser': 8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - eslint: 9.39.2(jiti@1.21.7) - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-react: 7.37.5(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-react-hooks: 5.2.0(eslint@9.39.2(jiti@1.21.7)) - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - eslint-import-resolver-webpack - - eslint-plugin-import-x - - supports-color - eslint-config-next@15.4.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: '@next/eslint-plugin-next': 15.4.0