[st] feat: 검증 이력 그리드 목데이터 작업

This commit is contained in:
2026-02-05 15:14:54 +09:00
parent f88d42493c
commit d08df3ff35
6 changed files with 606 additions and 374 deletions
+2 -1
View File
@@ -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",
@@ -1,6 +1,7 @@
"use client";
import { useState } from "react";
import { DataGrid } from "@rsone/components";
import SearchForm from "@/components/module/SearchForm";
import {
Button,
@@ -13,6 +14,8 @@ import {
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;
@@ -37,6 +40,11 @@ interface VerificationFormValues {
}
const ManagementVerificationRule = () => {
const [verificationHistoryRowData, setVerificationHistoryRowData] =
useState<Record<string, string | number>[]>(
verificationHistoryMockData,
);
const [formValues, setFormValues] = useState<VerificationFormValues>({
mu: "0",
percentile: "0",
@@ -90,379 +98,384 @@ const ManagementVerificationRule = () => {
};
return (
<>
<SearchForm />
<div className="card card-border mt-4">
<div className="p-2">
{/* 통계 검증 섹션 */}
<div className="mb-6">
<h3 className="px-2 text-[1.5rem] font-semibold">
통계 검증
</h3>
<div className="card card-border mt-4">
<div className="p-2">
{/* 통계 검증 섹션 */}
<div className="mb-6">
<h3 className="px-2 text-[1.5rem] font-semibold">
통계 검증
</h3>
<div className="flex gap-2">
{/* 왼쪽: 검증 변수 */}
<div className="card card-border flex-[0.5] rounded p-4">
<h4 className="mb-3 rounded bg-gray-100 p-2 text-[1.4rem] font-medium">
검증 변수
</h4>
<div className="flex gap-2">
{/* 왼쪽: 검증 변수 */}
<div className="card card-border flex-[0.5] rounded p-4">
<h4 className="mb-3 rounded bg-gray-100 p-2 text-[1.4rem] font-medium">
검증 변수
</h4>
<div className="space-y-3">
<div className="flex items-center gap-4">
<Label className="w-32 text-label">μ</Label>
<Input
type="number"
value={formValues.mu}
onChange={(e) =>
handleInputChange(
"mu",
e.target.value,
)
}
className="flex-1"
/>
</div>
<div className="space-y-3">
<div className="flex items-center gap-4">
<Label className="w-32 text-label">
μ
</Label>
<Input
type="number"
value={formValues.mu}
onChange={(e) =>
handleInputChange(
"mu",
e.target.value,
)
}
className="flex-1"
/>
</div>
<div className="flex items-center gap-4">
<Label className="w-32 text-label">
Percentile
</Label>
<Input
type="number"
value={formValues.percentile}
onChange={(e) =>
handleInputChange(
"percentile",
e.target.value,
)
}
className="flex-1"
/>
</div>
<div className="flex items-center gap-4">
<Label className="w-32 text-label">
Percentile
</Label>
<Input
type="number"
value={formValues.percentile}
onChange={(e) =>
handleInputChange(
"percentile",
e.target.value,
)
}
className="flex-1"
/>
</div>
<div className="flex items-center gap-4">
<Label className="w-32 text-label">A</Label>
<Input
type="number"
value={formValues.a}
onChange={(e) =>
handleInputChange(
"a",
e.target.value,
)
}
className="flex-1"
/>
</div>
<div className="flex items-center gap-4">
<Label className="w-32 text-label">
A
</Label>
<Input
type="number"
value={formValues.a}
onChange={(e) =>
handleInputChange(
"a",
e.target.value,
)
}
className="flex-1"
/>
</div>
<div className="flex items-center gap-4">
<Label className="w-32 text-label">C</Label>
<Input
type="number"
value={formValues.c}
onChange={(e) =>
handleInputChange(
"c",
e.target.value,
)
}
className="flex-1"
/>
</div>
<div className="flex items-center gap-4">
<Label className="w-32 text-label">
C
</Label>
<Input
type="number"
value={formValues.c}
onChange={(e) =>
handleInputChange(
"c",
e.target.value,
)
}
className="flex-1"
/>
</div>
<div className="flex items-center gap-4">
<Label className="w-32 text-label">
검증 년도
</Label>
<Select
value={formValues.verificationYear}
onValueChange={(value) =>
handleInputChange(
"verificationYear",
value,
)
}
>
<SelectTrigger className="flex-1">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="2025">
2025년
</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex items-center gap-4">
<Label className="w-32 text-label">
검증 년도
</Label>
<Select
value={formValues.verificationYear}
onValueChange={(value) =>
handleInputChange(
"verificationYear",
value,
)
}
>
<SelectTrigger className="flex-1">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="2025">
2025년
</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</div>
{/* 오른쪽: 검증 대상 */}
<div className="card card-border flex-1 rounded p-4">
<h4 className="mb-3 rounded bg-gray-100 p-2 text-[1.4rem] font-medium">
검증 대상
</h4>
{/* 오른쪽: 검증 대상 */}
<div className="card card-border flex-1 rounded p-4">
<h4 className="mb-3 rounded bg-gray-100 p-2 text-[1.4rem] font-medium">
검증 대상
</h4>
<div className="space-y-4 p-2">
<div className="grid grid-cols-4 gap-4">
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.sidoDistribution
}
onCheckedChange={() =>
handleCheckboxChange(
"sidoDistribution",
)
}
/>
<Label className="cursor-pointer text-label">
하수도 보급률
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.countyDistribution
}
onCheckedChange={() =>
handleCheckboxChange(
"countyDistribution",
)
}
/>
<Label className="cursor-pointer text-label">
하수관로
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.countyDistributionUserManagement
}
onCheckedChange={() =>
handleCheckboxChange(
"countyDistributionUserManagement",
)
}
/>
<Label className="cursor-pointer text-label">
하수관로 유지관리
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.lowerDistribution
}
onCheckedChange={() =>
handleCheckboxChange(
"lowerDistribution",
)
}
/>
<Label className="cursor-pointer text-label">
하수저류시설 및 빗물펌프장
</Label>
</div>
<div className="space-y-4 p-2">
<div className="grid grid-cols-4 gap-4">
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.sidoDistribution
}
onCheckedChange={() =>
handleCheckboxChange(
"sidoDistribution",
)
}
/>
<Label className="cursor-pointer text-label">
하수도 보급률
</Label>
</div>
<div className="grid grid-cols-4 gap-4">
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.sidoServiceAvailability
}
onCheckedChange={() =>
handleCheckboxChange(
"sidoServiceAvailability",
)
}
/>
<Label className="cursor-pointer text-label">
펌프장
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.individualService
}
onCheckedChange={() =>
handleCheckboxChange(
"individualService",
)
}
/>
<Label className="cursor-pointer text-label">
공공하수처리시설
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.sidoServiceAvailability
}
onCheckedChange={() =>
handleCheckboxChange(
"sidoServiceAvailability",
)
}
/>
<Label className="cursor-pointer text-label">
분뇨처리시설
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.individualService
}
onCheckedChange={() =>
handleCheckboxChange(
"individualService",
)
}
/>
<Label className="cursor-pointer text-label">
개인하수처리시설
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.countyDistribution
}
onCheckedChange={() =>
handleCheckboxChange(
"countyDistribution",
)
}
/>
<Label className="cursor-pointer text-label">
하수관로
</Label>
</div>
<div className="grid grid-cols-4 gap-4">
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.lowerOrgStatistics
}
onCheckedChange={() =>
handleCheckboxChange(
"lowerOrgStatistics",
)
}
/>
<Label className="cursor-pointer text-label">
하수도재정
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.studentStatistics
}
onCheckedChange={() =>
handleCheckboxChange(
"studentStatistics",
)
}
/>
<Label className="cursor-pointer text-label">
물 재이용
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.lowerOrgStatistics
}
onCheckedChange={() =>
handleCheckboxChange(
"lowerOrgStatistics",
)
}
/>
<Label className="cursor-pointer text-label">
하수 및 분뇨찌꺼기(슬러지) 처리
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.studentStatistics
}
onCheckedChange={() =>
handleCheckboxChange(
"studentStatistics",
)
}
/>
<Label className="cursor-pointer text-label">
하수 및 분뇨관련산업
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.countyDistributionUserManagement
}
onCheckedChange={() =>
handleCheckboxChange(
"countyDistributionUserManagement",
)
}
/>
<Label className="cursor-pointer text-label">
하수관로 유지관리
</Label>
</div>
<div className="grid grid-cols-4 gap-4">
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.lowerManagementEnterprise
}
onCheckedChange={() =>
handleCheckboxChange(
"lowerManagementEnterprise",
)
}
/>
<Label className="cursor-pointer text-label">
하수도 서비스 수준
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.lowerDistribution
}
onCheckedChange={() =>
handleCheckboxChange(
"lowerDistribution",
)
}
/>
<Label className="cursor-pointer text-label">
하수저류시설 및 빗물펌프장
</Label>
</div>
</div>
<div className="grid grid-cols-4 gap-4">
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.sidoServiceAvailability
}
onCheckedChange={() =>
handleCheckboxChange(
"sidoServiceAvailability",
)
}
/>
<Label className="cursor-pointer text-label">
펌프장
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.individualService
}
onCheckedChange={() =>
handleCheckboxChange(
"individualService",
)
}
/>
<Label className="cursor-pointer text-label">
공공하수처리시설
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.sidoServiceAvailability
}
onCheckedChange={() =>
handleCheckboxChange(
"sidoServiceAvailability",
)
}
/>
<Label className="cursor-pointer text-label">
분뇨처리시설
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.individualService
}
onCheckedChange={() =>
handleCheckboxChange(
"individualService",
)
}
/>
<Label className="cursor-pointer text-label">
개인하수처리시설
</Label>
</div>
</div>
<div className="grid grid-cols-4 gap-4">
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.lowerOrgStatistics
}
onCheckedChange={() =>
handleCheckboxChange(
"lowerOrgStatistics",
)
}
/>
<Label className="cursor-pointer text-label">
하수도재정
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.studentStatistics
}
onCheckedChange={() =>
handleCheckboxChange(
"studentStatistics",
)
}
/>
<Label className="cursor-pointer text-label">
물 재이용
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.lowerOrgStatistics
}
onCheckedChange={() =>
handleCheckboxChange(
"lowerOrgStatistics",
)
}
/>
<Label className="cursor-pointer text-label">
하수 및 분뇨찌꺼기(슬러지) 처리
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.studentStatistics
}
onCheckedChange={() =>
handleCheckboxChange(
"studentStatistics",
)
}
/>
<Label className="cursor-pointer text-label">
하수 및 분뇨관련산업
</Label>
</div>
</div>
<div className="grid grid-cols-4 gap-4">
<div className="flex items-center gap-2">
<Checkbox
checked={
formValues.checkboxOptions
.lowerManagementEnterprise
}
onCheckedChange={() =>
handleCheckboxChange(
"lowerManagementEnterprise",
)
}
/>
<Label className="cursor-pointer text-label">
하수도 서비스 수준
</Label>
</div>
</div>
</div>
</div>
</div>
</div>
{/* 버튼 */}
<div className="mt-6 flex justify-center gap-4 border-t pt-4">
<Button
color="green"
className="h-[3.6rem] w-[120px]"
onClick={handleSubmit}
>
검증 실행
</Button>
<Button
color="gray"
className="h-[3.6rem] w-[120px]"
onClick={handleReset}
>
초기화
</Button>
</div>
{/* 버튼 */}
<div className="mt-6 flex justify-center gap-4 pt-4">
<Button
color="green"
className="h-[3.6rem] w-[120px]"
onClick={handleSubmit}
>
검증 실행
</Button>
<Button
color="gray"
className="h-[3.6rem] w-[120px]"
onClick={handleReset}
>
초기화
</Button>
</div>
{/* 검증 이력 섹션 */}
<div className="mt-8 border-t pt-6">
<h3 className="mb-4 px-2 text-[1.5rem] font-semibold">
검증 이력
</h3>
<DataGrid
columnInfo={verificationHistoryColumnInfo}
rowData={verificationHistoryRowData}
setRowData={setVerificationHistoryRowData}
isExcelImport={false}
isExcelExport={false}
showHeaderCheckbox={false}
/>
</div>
</div>
</>
</div>
);
};
@@ -0,0 +1,120 @@
import { ValueType } from "realgrid";
import type { ColumnInfo } from "@rsone/components";
/** 검증 이력 그리드 컬럼 설정 */
export const verificationHistoryColumnInfo: ColumnInfo = {
columns: [
{
name: "executedAt",
fieldName: "executedAt",
header: { text: "검증 실행 일시" },
editable: false,
sortdisable: false,
},
{
name: "progressStatus",
fieldName: "progressStatus",
header: { text: "진행 상태" },
editable: false,
sortdisable: false,
},
{
name: "endedAt",
fieldName: "endedAt",
header: { text: "종료 일시" },
editable: false,
sortdisable: false,
},
{
name: "verificationYear",
fieldName: "verificationYear",
header: { text: "검증년도" },
editable: false,
sortdisable: false,
},
{
name: "mu",
fieldName: "mu",
header: { text: "μ" },
editable: false,
sortdisable: false,
valueType: ValueType.NUMBER,
dataFormat: "#,##0.###",
},
{
name: "percentile",
fieldName: "percentile",
header: { text: "Percentile" },
editable: false,
sortdisable: false,
valueType: ValueType.NUMBER,
dataFormat: "#,##0.###",
},
{
name: "a",
fieldName: "a",
header: { text: "A" },
editable: false,
sortdisable: false,
valueType: ValueType.NUMBER,
dataFormat: "#,##0.###",
},
{
name: "c",
fieldName: "c",
header: { text: "C" },
editable: false,
sortdisable: false,
valueType: ValueType.NUMBER,
dataFormat: "#,##0.###",
},
{
name: "target",
fieldName: "target",
header: { text: "검증 대상" },
editable: false,
sortdisable: false,
},
{
name: "normalCount",
fieldName: "normalCount",
header: { text: "정상건수" },
editable: false,
sortdisable: false,
valueType: ValueType.NUMBER,
dataFormat: "#,##0",
},
{
name: "excludedCount",
fieldName: "excludedCount",
header: { text: "제외건수" },
editable: false,
sortdisable: false,
valueType: ValueType.NUMBER,
dataFormat: "#,##0",
},
{
name: "abnormalCount",
fieldName: "abnormalCount",
header: { text: "이상건수" },
editable: false,
sortdisable: false,
valueType: ValueType.NUMBER,
dataFormat: "#,##0",
},
],
columnLayout: [
"executedAt",
"progressStatus",
"endedAt",
"verificationYear",
"mu",
"percentile",
"a",
"c",
"target",
"normalCount",
"excludedCount",
"abnormalCount",
],
};
@@ -0,0 +1,27 @@
/** 검증 이력 한 건 (그리드 행 데이터) */
export interface VerificationHistoryItem {
/** 검증 실행 일시 */
executedAt: string;
/** 진행 상태 */
progressStatus: string;
/** 종료 일시 */
endedAt: string;
/** 검증년도 */
verificationYear: string;
/** μ */
mu: number;
/** Percentile */
percentile: number;
/** A */
a: number;
/** C */
c: number;
/** 검증 대상 */
target: string;
/** 정상건수 */
normalCount: number;
/** 제외건수 */
excludedCount: number;
/** 이상건수 */
abnormalCount: number;
}
@@ -0,0 +1,67 @@
import { fakerKO as faker } from "@faker-js/faker";
import type { VerificationHistoryItem } from "./verification-history-interface";
const VERIFICATION_TARGETS = [
"하수도 보급률",
"하수관로",
"하수관로 유지관리",
"하수저류시설 및 빗물펌프장",
"펌프장",
"공공하수처리시설",
"분뇨처리시설",
"개인하수처리시설",
"하수도재정",
"물 재이용",
"하수도 서비스 수준",
];
const PROGRESS_STATUSES = ["대기", "진행중", "완료", "실패"];
function formatDateTime(date: Date): string {
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, "0");
const d = String(date.getDate()).padStart(2, "0");
const h = String(date.getHours()).padStart(2, "0");
const min = String(date.getMinutes()).padStart(2, "0");
return `${y}-${m}-${d} ${h}:${min}`;
}
/** 검증 이력 목데이터 생성 (그리드 행 형식) */
export function createVerificationHistoryMock(
count = 10,
): Record<string, string | number>[] {
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<string, string | number>;
});
}
/** 검증 이력 기본 목데이터 (10건) */
export const verificationHistoryMockData = createVerificationHistoryMock(10);
+28 -24
View File
@@ -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