@skspwork/config-doc 2.0.3 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/package.json +3 -2
  2. package/packages/web/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  3. package/packages/web/.next/standalone/.next/server/app/_not-found.html +1 -1
  4. package/packages/web/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  5. package/packages/web/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  6. package/packages/web/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  7. package/packages/web/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  8. package/packages/web/.next/standalone/.next/server/app/api/config/save/route.js +1 -1
  9. package/packages/web/.next/standalone/.next/server/app/api/config/save/route.js.nft.json +1 -1
  10. package/packages/web/.next/standalone/.next/server/app/api/export/route.js +3 -3
  11. package/packages/web/.next/standalone/.next/server/app/api/export/route.js.nft.json +1 -1
  12. package/packages/web/.next/standalone/.next/server/app/index.html +1 -1
  13. package/packages/web/.next/standalone/.next/server/app/index.rsc +3 -3
  14. package/packages/web/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  15. package/packages/web/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  16. package/packages/web/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  17. package/packages/web/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  18. package/packages/web/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  19. package/packages/web/.next/standalone/.next/server/chunks/[root-of-the-server]__40e87302._.js +3 -0
  20. package/packages/web/.next/standalone/.next/server/chunks/[root-of-the-server]__93da9fce._.js +1 -1
  21. package/packages/web/.next/standalone/.next/server/chunks/[root-of-the-server]__c9655ac8._.js +3 -0
  22. package/packages/web/.next/standalone/.next/server/chunks/[root-of-the-server]__e19366f6._.js +1 -1
  23. package/packages/web/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_d09de205.js +368 -29
  24. package/packages/web/.next/standalone/.next/server/chunks/ssr/app_page_tsx_55b2e5ee._.js +1 -1
  25. package/packages/web/.next/standalone/.next/server/pages/404.html +1 -1
  26. package/packages/web/.next/standalone/.next/static/chunks/02de70e4c30afe2f.js +1 -0
  27. package/packages/web/.next/standalone/.next/static/chunks/862e384b52cfebf3.css +3 -0
  28. package/packages/web/.next/standalone/app/api/config/metadata/route.ts +5 -3
  29. package/packages/web/.next/standalone/package.json +2 -0
  30. package/packages/web/.next/standalone/playwright-report/index.html +1 -1
  31. package/packages/web/.next/static/chunks/02de70e4c30afe2f.js +1 -0
  32. package/packages/web/.next/static/chunks/862e384b52cfebf3.css +3 -0
  33. package/packages/web/package.json +2 -0
  34. package/packages/web/.next/standalone/.next/server/chunks/[root-of-the-server]__1a68b1f3._.js +0 -3
  35. package/packages/web/.next/standalone/.next/server/chunks/[root-of-the-server]__2c94dfea._.js +0 -3
  36. package/packages/web/.next/standalone/.next/static/chunks/4bbca8cd642026de.css +0 -3
  37. package/packages/web/.next/standalone/.next/static/chunks/54e2bd8f072e7d4e.js +0 -1
  38. package/packages/web/.next/standalone/app/api/config/load/route.ts +0 -57
  39. package/packages/web/.next/standalone/app/api/config/save/route.ts +0 -73
  40. package/packages/web/.next/standalone/app/api/export/route.ts +0 -75
  41. package/packages/web/.next/standalone/app/api/export/settings/route.ts +0 -144
  42. package/packages/web/.next/standalone/app/api/files/browse/route.ts +0 -46
  43. package/packages/web/.next/standalone/app/api/project/route.ts +0 -41
  44. package/packages/web/.next/standalone/app/globals.css +0 -26
  45. package/packages/web/.next/standalone/app/icon.svg +0 -41
  46. package/packages/web/.next/standalone/app/layout.tsx +0 -34
  47. package/packages/web/.next/standalone/app/page.tsx +0 -135
  48. package/packages/web/.next/standalone/components/ConfigFileTabs.tsx +0 -188
  49. package/packages/web/.next/standalone/components/ConfigTree.tsx +0 -176
  50. package/packages/web/.next/standalone/components/EditableList.tsx +0 -337
  51. package/packages/web/.next/standalone/components/ExportDialog.tsx +0 -234
  52. package/packages/web/.next/standalone/components/FieldsEditor.tsx +0 -92
  53. package/packages/web/.next/standalone/components/FileBrowser.tsx +0 -290
  54. package/packages/web/.next/standalone/components/Header.tsx +0 -37
  55. package/packages/web/.next/standalone/components/PropertyEditor.tsx +0 -102
  56. package/packages/web/.next/standalone/components/TagEditor.tsx +0 -86
  57. package/packages/web/.next/standalone/components/Toast.tsx +0 -91
  58. package/packages/web/.next/standalone/eslint.config.mjs +0 -18
  59. package/packages/web/.next/standalone/hooks/useConfigManager.ts +0 -633
  60. package/packages/web/.next/standalone/lib/configParser.ts +0 -155
  61. package/packages/web/.next/standalone/lib/fileSystem.ts +0 -186
  62. package/packages/web/.next/standalone/lib/getRootPath.ts +0 -45
  63. package/packages/web/.next/standalone/lib/htmlGenerator.ts +0 -839
  64. package/packages/web/.next/standalone/lib/jsonUtils.ts +0 -26
  65. package/packages/web/.next/standalone/lib/markdownGenerator.ts +0 -79
  66. package/packages/web/.next/standalone/lib/markdownTableGenerator.ts +0 -107
  67. package/packages/web/.next/standalone/lib/storage.ts +0 -104
  68. package/packages/web/.next/standalone/lib/utils.ts +0 -72
  69. package/packages/web/.next/standalone/next.config.ts +0 -10
  70. package/packages/web/.next/standalone/package-lock.json +0 -7977
  71. package/packages/web/.next/standalone/playwright.config.ts +0 -27
  72. package/packages/web/.next/standalone/postcss.config.mjs +0 -7
  73. package/packages/web/.next/standalone/test-results/.last-run.json +0 -4
  74. package/packages/web/.next/standalone/tsconfig.json +0 -34
  75. package/packages/web/.next/standalone/tsconfig.tsbuildinfo +0 -1
  76. package/packages/web/.next/standalone/types/index.ts +0 -74
  77. package/packages/web/.next/standalone/vitest.config.ts +0 -14
  78. package/packages/web/.next/static/chunks/4bbca8cd642026de.css +0 -3
  79. package/packages/web/.next/static/chunks/54e2bd8f072e7d4e.js +0 -1
@@ -1,73 +0,0 @@
1
- import { NextRequest, NextResponse } from 'next/server';
2
- import { FileSystemService } from '@/lib/fileSystem';
3
- import { StorageService } from '@/lib/storage';
4
- import { getRootPath } from '@/lib/getRootPath';
5
-
6
- export async function POST(request: NextRequest) {
7
- try {
8
- let body;
9
- try {
10
- body = await request.json();
11
- } catch {
12
- return NextResponse.json(
13
- { success: false, error: 'Invalid JSON body' },
14
- { status: 400 }
15
- );
16
- }
17
- const { configFilePath, propertyPath, propertyDoc, properties } = body;
18
-
19
- // configFilePathは必須
20
- if (!configFilePath) {
21
- return NextResponse.json(
22
- { success: false, error: 'Missing configFilePath' },
23
- { status: 400 }
24
- );
25
- }
26
-
27
- // プロジェクトのルートパス(ユーザーの作業ディレクトリ)
28
- const rootPath = getRootPath();
29
- const fsService = new FileSystemService(rootPath);
30
- const storageService = new StorageService(fsService);
31
-
32
- // .config_docディレクトリを確保
33
- await fsService.ensureConfigDocDir();
34
-
35
- // 一括更新モード(propertiesが指定されている場合)
36
- if (properties) {
37
- await storageService.updateAllProperties(configFilePath, properties);
38
- } else if (propertyPath && propertyDoc) {
39
- // 単一プロパティ更新モード
40
- await storageService.savePropertyDoc(
41
- configFilePath,
42
- propertyPath,
43
- propertyDoc
44
- );
45
- } else {
46
- return NextResponse.json(
47
- { success: false, error: 'Missing required fields: either (propertyPath, propertyDoc) or properties required' },
48
- { status: 400 }
49
- );
50
- }
51
-
52
- // メタデータの最終更新時刻を更新
53
- const metadata = await fsService.loadConfigFiles();
54
- if (metadata) {
55
- metadata.lastModified = new Date().toISOString();
56
- await fsService.saveConfigFiles(metadata);
57
- }
58
-
59
- return NextResponse.json({
60
- success: true,
61
- message: 'ドキュメントを保存しました'
62
- });
63
- } catch (error) {
64
- console.error('API Error:', error);
65
- return NextResponse.json(
66
- {
67
- success: false,
68
- error: error instanceof Error ? error.message : 'Unknown error'
69
- },
70
- { status: 500 }
71
- );
72
- }
73
- }
@@ -1,75 +0,0 @@
1
- import { NextRequest, NextResponse } from 'next/server';
2
- import { HtmlGenerator } from '@/lib/htmlGenerator';
3
- import { MarkdownGenerator } from '@/lib/markdownGenerator';
4
- import { MarkdownTableGenerator } from '@/lib/markdownTableGenerator';
5
- import { FileSystemService } from '@/lib/fileSystem';
6
- import { getRootPath } from '@/lib/getRootPath';
7
- import path from 'path';
8
- import fs from 'fs/promises';
9
-
10
- export async function POST(request: NextRequest) {
11
- try {
12
- const rootPath = getRootPath();
13
-
14
- // リクエストボディからフォーマット、ファイル名、出力先フォルダを取得
15
- let body;
16
- try {
17
- body = await request.json();
18
- } catch {
19
- body = {};
20
- }
21
- const { format = 'html' } = body;
22
- // fileNameが空文字列の場合はデフォルト値を使用
23
- const fileName = body.fileName?.trim() || 'config-doc';
24
- // outputDirが空文字列の場合はプロジェクトルートに出力
25
- const outputDir = body.outputDir?.trim() || '';
26
-
27
- // フォーマットに応じてジェネレーターを選択
28
- let content: string;
29
-
30
- if (format === 'markdown') {
31
- const generator = new MarkdownGenerator(rootPath);
32
- content = await generator.generateMarkdown();
33
- } else if (format === 'markdown-table') {
34
- const generator = new MarkdownTableGenerator(rootPath);
35
- content = await generator.generateMarkdownTable();
36
- } else {
37
- // デフォルトはHTML
38
- const generator = new HtmlGenerator(rootPath);
39
- content = await generator.generateHtml();
40
- }
41
-
42
- // 出力ファイル名を決定(拡張子付き)
43
- const extension = (format === 'markdown' || format === 'markdown-table') ? 'md' : 'html';
44
- const outputFileName = `${fileName}.${extension}`;
45
-
46
- // 出力パス: {outputDir}/{fileName}.{extension}(outputDirが空ならルート直下)
47
- const fsService = new FileSystemService(rootPath);
48
- await fsService.ensureConfigDocDir();
49
- const outputPath = outputDir
50
- ? path.join(rootPath, outputDir, outputFileName)
51
- : path.join(rootPath, outputFileName);
52
-
53
- // ディレクトリを確保
54
- const outputDirPath = path.dirname(outputPath);
55
- await fs.mkdir(outputDirPath, { recursive: true });
56
-
57
- // ファイルを保存
58
- await fs.writeFile(outputPath, content, 'utf-8');
59
-
60
- return NextResponse.json({
61
- success: true,
62
- message: `${format === 'markdown' ? 'Markdown' : 'HTML'}ファイルを生成しました`,
63
- outputPath
64
- });
65
- } catch (error) {
66
- console.error('API Error:', error);
67
- return NextResponse.json(
68
- {
69
- success: false,
70
- error: error instanceof Error ? error.message : 'Unknown error'
71
- },
72
- { status: 500 }
73
- );
74
- }
75
- }
@@ -1,144 +0,0 @@
1
- import { NextRequest, NextResponse } from 'next/server';
2
- import { getRootPath } from '@/lib/getRootPath';
3
- import path from 'path';
4
- import fs from 'fs/promises';
5
- import { ExportSettings, UserSettings, ProjectSettings } from '@/types';
6
- import { FileSystemService } from '@/lib/fileSystem';
7
- import { parseJSON } from '@/lib/jsonUtils';
8
-
9
- const USER_SETTINGS_FILE = '.user_settings.json';
10
- const CONFIG_DOC_DIR = '.config_doc';
11
-
12
- // GET: エクスポート設定を読み込み
13
- export async function GET() {
14
- try {
15
- const rootPath = getRootPath();
16
- const fsService = new FileSystemService(rootPath);
17
- const userSettingsPath = path.join(rootPath, CONFIG_DOC_DIR, USER_SETTINGS_FILE);
18
-
19
- // ユーザ設定を読み込み
20
- let userSettings: UserSettings;
21
- try {
22
- const content = await fs.readFile(userSettingsPath, 'utf-8');
23
- userSettings = parseJSON<UserSettings>(content);
24
- } catch {
25
- // デフォルトのユーザ設定
26
- userSettings = {
27
- format: 'html',
28
- autoExport: true
29
- };
30
- }
31
-
32
- // プロジェクト設定から export.fileName と outputDir を取得
33
- // outputDirは空文字も有効な値(プロジェクトルートを意味する)なので、undefinedのみデフォルト値を使用
34
- const projectSettings = await fsService.loadProjectSettings();
35
- const fileName = projectSettings?.export?.fileName || 'config-doc';
36
- const outputDir = projectSettings?.export?.outputDir !== undefined
37
- ? projectSettings.export.outputDir
38
- : '.config_doc/output';
39
-
40
- // 統合された設定を返す
41
- const settings: ExportSettings = {
42
- ...userSettings,
43
- fileName,
44
- outputDir
45
- };
46
-
47
- return NextResponse.json({
48
- success: true,
49
- data: settings
50
- });
51
- } catch (error) {
52
- console.error('Failed to load export settings:', error);
53
- return NextResponse.json(
54
- {
55
- success: false,
56
- error: error instanceof Error ? error.message : 'Unknown error'
57
- },
58
- { status: 500 }
59
- );
60
- }
61
- }
62
-
63
- // POST: エクスポート設定を保存
64
- export async function POST(request: NextRequest) {
65
- try {
66
- let body;
67
- try {
68
- body = await request.json();
69
- } catch {
70
- return NextResponse.json(
71
- { success: false, error: 'Invalid JSON body' },
72
- { status: 400 }
73
- );
74
- }
75
- const settings: ExportSettings = body.settings;
76
-
77
- if (!settings || !settings.format) {
78
- return NextResponse.json(
79
- { success: false, error: 'Invalid settings' },
80
- { status: 400 }
81
- );
82
- }
83
-
84
- const rootPath = getRootPath();
85
- const fsService = new FileSystemService(rootPath);
86
- const configDocDir = path.join(rootPath, CONFIG_DOC_DIR);
87
-
88
- // .config_doc ディレクトリを確保
89
- await fs.mkdir(configDocDir, { recursive: true });
90
-
91
- // ユーザ設定を保存(format, autoExport, lastExportedAt)
92
- const userSettings: UserSettings = {
93
- format: settings.format,
94
- autoExport: settings.autoExport,
95
- lastExportedAt: settings.lastExportedAt
96
- };
97
- const userSettingsPath = path.join(configDocDir, USER_SETTINGS_FILE);
98
- await fs.writeFile(
99
- userSettingsPath,
100
- JSON.stringify(userSettings, null, 2),
101
- 'utf-8'
102
- );
103
-
104
- // プロジェクト設定の export.fileName と outputDir を更新
105
- if (settings.fileName !== undefined || settings.outputDir !== undefined) {
106
- const existingProjectSettings = await fsService.loadProjectSettings();
107
-
108
- if (existingProjectSettings) {
109
- // 既存の設定を更新
110
- existingProjectSettings.export = {
111
- ...existingProjectSettings.export,
112
- fileName: settings.fileName ?? existingProjectSettings.export?.fileName,
113
- outputDir: settings.outputDir ?? existingProjectSettings.export?.outputDir
114
- };
115
- await fsService.saveProjectSettings(existingProjectSettings);
116
- } else {
117
- // 新規作成
118
- const newProjectSettings: ProjectSettings = {
119
- projectName: path.basename(rootPath),
120
- configFiles: [],
121
- export: {
122
- fileName: settings.fileName,
123
- outputDir: settings.outputDir
124
- }
125
- };
126
- await fsService.saveProjectSettings(newProjectSettings);
127
- }
128
- }
129
-
130
- return NextResponse.json({
131
- success: true,
132
- message: 'Export settings saved'
133
- });
134
- } catch (error) {
135
- console.error('Failed to save export settings:', error);
136
- return NextResponse.json(
137
- {
138
- success: false,
139
- error: error instanceof Error ? error.message : 'Unknown error'
140
- },
141
- { status: 500 }
142
- );
143
- }
144
- }
@@ -1,46 +0,0 @@
1
- import { NextRequest, NextResponse } from 'next/server';
2
- import { FileSystemService } from '@/lib/fileSystem';
3
- import { getRootPath } from '@/lib/getRootPath';
4
-
5
- export async function POST(request: NextRequest) {
6
- try {
7
- let body: { directory?: string } = {};
8
- try {
9
- body = await request.json();
10
- } catch {
11
- // 空のボディの場合は無視
12
- }
13
- const { directory } = body;
14
-
15
- if (!directory) {
16
- return NextResponse.json(
17
- { success: false, error: 'directory is required' },
18
- { status: 400 }
19
- );
20
- }
21
-
22
- // プロジェクトのルートパス(ユーザーの作業ディレクトリ)
23
- const rootPath = getRootPath();
24
- const fsService = new FileSystemService(rootPath);
25
-
26
- // ディレクトリ内のファイル一覧を取得
27
- const items = await fsService.browseDirectory(directory);
28
-
29
- return NextResponse.json({
30
- success: true,
31
- data: {
32
- currentPath: directory,
33
- items
34
- }
35
- });
36
- } catch (error) {
37
- console.error('API Error:', error);
38
- return NextResponse.json(
39
- {
40
- success: false,
41
- error: error instanceof Error ? error.message : 'Unknown error'
42
- },
43
- { status: 500 }
44
- );
45
- }
46
- }
@@ -1,41 +0,0 @@
1
- import { NextResponse } from 'next/server';
2
- import path from 'path';
3
- import fs from 'fs/promises';
4
- import { getRootPath } from '@/lib/getRootPath';
5
-
6
- export async function GET() {
7
- try {
8
- // プロジェクトのルートパスを取得(ユーザーの作業ディレクトリ)
9
- const rootPath = getRootPath();
10
- const projectName = path.basename(rootPath);
11
-
12
- // .config_docディレクトリの存在確認
13
- const ConfigDocPath = path.join(rootPath, '.config_doc');
14
- let hasConfigDoc = false;
15
-
16
- try {
17
- await fs.access(ConfigDocPath);
18
- hasConfigDoc = true;
19
- } catch {
20
- hasConfigDoc = false;
21
- }
22
-
23
- return NextResponse.json({
24
- success: true,
25
- data: {
26
- projectName,
27
- rootPath,
28
- hasConfigDoc
29
- }
30
- });
31
- } catch (error) {
32
- console.error('API Error:', error);
33
- return NextResponse.json(
34
- {
35
- success: false,
36
- error: error instanceof Error ? error.message : 'Unknown error'
37
- },
38
- { status: 500 }
39
- );
40
- }
41
- }
@@ -1,26 +0,0 @@
1
- @import "tailwindcss";
2
-
3
- :root {
4
- --background: #ffffff;
5
- --foreground: #171717;
6
- }
7
-
8
- @theme inline {
9
- --color-background: var(--background);
10
- --color-foreground: var(--foreground);
11
- --font-sans: var(--font-geist-sans);
12
- --font-mono: var(--font-geist-mono);
13
- }
14
-
15
- @media (prefers-color-scheme: dark) {
16
- :root {
17
- --background: #0a0a0a;
18
- --foreground: #ededed;
19
- }
20
- }
21
-
22
- body {
23
- background: var(--background);
24
- color: var(--foreground);
25
- font-family: Arial, Helvetica, sans-serif;
26
- }
@@ -1,41 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" fill="none">
2
- <defs>
3
- <linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
4
- <stop offset="0%" style="stop-color:#3B82F6"/>
5
- <stop offset="50%" style="stop-color:#6366F1"/>
6
- <stop offset="100%" style="stop-color:#8B5CF6"/>
7
- </linearGradient>
8
- <linearGradient id="docGradient" x1="0%" y1="0%" x2="100%" y2="100%">
9
- <stop offset="0%" style="stop-color:#60A5FA"/>
10
- <stop offset="100%" style="stop-color:#A78BFA"/>
11
- </linearGradient>
12
- </defs>
13
-
14
- <!-- 背景の角丸四角 -->
15
- <rect x="8" y="8" width="224" height="224" rx="44" fill="url(#bgGradient)"/>
16
-
17
- <!-- ドキュメントアイコン(背面) -->
18
- <path d="M68 48 L148 48 L172 72 L172 192 L68 192 Z" fill="white" opacity="0.2"/>
19
- <path d="M148 48 L148 72 L172 72" fill="none" stroke="white" stroke-width="4" opacity="0.2"/>
20
-
21
- <!-- ドキュメントアイコン(前面) -->
22
- <path d="M52 64 L132 64 L156 88 L156 208 L52 208 Z" fill="white"/>
23
- <path d="M132 64 L132 88 L156 88" fill="none" stroke="url(#docGradient)" stroke-width="4"/>
24
-
25
- <!-- JSON括弧 { } -->
26
- <text x="104" y="152" font-family="Monaco, Consolas, monospace" font-size="48" font-weight="bold" fill="url(#bgGradient)" text-anchor="middle">{ }</text>
27
-
28
- <!-- 歯車(右下) -->
29
- <circle cx="188" cy="188" r="40" fill="url(#docGradient)"/>
30
- <circle cx="188" cy="188" r="16" fill="white"/>
31
- <g fill="url(#docGradient)">
32
- <rect x="182" y="144" width="12" height="16" rx="4"/>
33
- <rect x="182" y="216" width="12" height="16" rx="4"/>
34
- <rect x="144" y="182" width="16" height="12" rx="4"/>
35
- <rect x="216" y="182" width="16" height="12" rx="4"/>
36
- <rect x="152" y="152" width="12" height="16" rx="4" transform="rotate(45 158 160)"/>
37
- <rect x="212" y="212" width="12" height="16" rx="4" transform="rotate(45 218 220)"/>
38
- <rect x="212" y="152" width="12" height="16" rx="4" transform="rotate(-45 218 160)"/>
39
- <rect x="152" y="212" width="12" height="16" rx="4" transform="rotate(-45 158 220)"/>
40
- </g>
41
- </svg>
@@ -1,34 +0,0 @@
1
- import type { Metadata } from "next";
2
- import { Geist, Geist_Mono } from "next/font/google";
3
- import "./globals.css";
4
-
5
- const geistSans = Geist({
6
- variable: "--font-geist-sans",
7
- subsets: ["latin"],
8
- });
9
-
10
- const geistMono = Geist_Mono({
11
- variable: "--font-geist-mono",
12
- subsets: ["latin"],
13
- });
14
-
15
- export const metadata: Metadata = {
16
- title: "ConfigDoc Web",
17
- description: "設定ファイルのドキュメント化ツール",
18
- };
19
-
20
- export default function RootLayout({
21
- children,
22
- }: Readonly<{
23
- children: React.ReactNode;
24
- }>) {
25
- return (
26
- <html lang="ja">
27
- <body
28
- className={`${geistSans.variable} ${geistMono.variable} antialiased`}
29
- >
30
- {children}
31
- </body>
32
- </html>
33
- );
34
- }
@@ -1,135 +0,0 @@
1
- 'use client';
2
-
3
- import { useState } from 'react';
4
- import { FileTextIcon } from 'lucide-react';
5
- import { Header } from '@/components/Header';
6
- import { ConfigFileTabs } from '@/components/ConfigFileTabs';
7
- import { PropertyEditor } from '@/components/PropertyEditor';
8
- import { ConfigTree } from '@/components/ConfigTree';
9
- import { FileBrowser } from '@/components/FileBrowser';
10
- import { ExportDialog } from '@/components/ExportDialog';
11
- import { ToastContainer } from '@/components/Toast';
12
- import { useConfigManager } from '@/hooks/useConfigManager';
13
-
14
- export default function Home() {
15
- const [isFileBrowserOpen, setIsFileBrowserOpen] = useState(false);
16
- const [isExportDialogOpen, setIsExportDialogOpen] = useState(false);
17
-
18
- const {
19
- loadedConfigs,
20
- activeConfigIndex,
21
- activeConfig,
22
- selectedPath,
23
- editingDoc,
24
- originalDoc,
25
- hasUnsavedChanges,
26
- exportSettings,
27
- availableTags,
28
- projectFields,
29
- toasts,
30
- rootPath,
31
-
32
- setActiveConfigIndex,
33
- setEditingDoc,
34
- setHasUnsavedChanges,
35
- removeToast,
36
- handleSelectConfigFiles,
37
- handleRemoveConfig,
38
- handleReorderConfigs,
39
- handleSelectProperty,
40
- handleSaveProperty,
41
- handleExport,
42
- handleAvailableTagsChange,
43
- handleProjectFieldsChange,
44
- checkForChanges,
45
- resetSelection
46
- } = useConfigManager();
47
-
48
- return (
49
- <div className="min-h-screen bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50">
50
- {/* ヘッダー */}
51
- <Header onExportClick={() => setIsExportDialogOpen(true)} />
52
-
53
- {/* メインコンテンツ */}
54
- <main className="container mx-auto px-6 py-8">
55
- {/* ファイル選択セクション */}
56
- <ConfigFileTabs
57
- loadedConfigs={loadedConfigs}
58
- activeConfigIndex={activeConfigIndex}
59
- onTabClick={(index) => {
60
- setActiveConfigIndex(index);
61
- resetSelection();
62
- }}
63
- onRemoveConfig={handleRemoveConfig}
64
- onAddFileClick={() => setIsFileBrowserOpen(true)}
65
- onReorder={handleReorderConfigs}
66
- />
67
-
68
- {/* ツリーと詳細パネル */}
69
- {activeConfig && (
70
- <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
71
- {/* 左パネル: JSON構造ツリー */}
72
- <div className="bg-white/90 backdrop-blur-sm rounded-2xl shadow-xl border border-gray-100 p-6 flex flex-col max-h-[calc(100vh-190px)] hover:shadow-2xl transition-shadow duration-300">
73
- <div className="flex items-center gap-2 mb-4">
74
- <div className="w-8 h-8 bg-gradient-to-br from-purple-500 to-purple-600 rounded-lg flex items-center justify-center">
75
- <FileTextIcon className="w-5 h-5 text-white" />
76
- </div>
77
- <h2 className="text-xl font-bold text-gray-800">JSON構造</h2>
78
- </div>
79
- <div className="overflow-y-auto flex-1">
80
- <ConfigTree
81
- config={activeConfig.configData}
82
- docs={activeConfig.docs}
83
- onSelectProperty={handleSelectProperty}
84
- onEditProperty={handleSelectProperty}
85
- selectedPath={selectedPath}
86
- />
87
- </div>
88
- </div>
89
-
90
- {/* 右パネル: プロパティ詳細 */}
91
- <PropertyEditor
92
- selectedPath={selectedPath}
93
- editingDoc={editingDoc}
94
- hasUnsavedChanges={hasUnsavedChanges}
95
- availableTags={availableTags}
96
- projectFields={projectFields}
97
- onEditingDocChange={(doc) => {
98
- setEditingDoc(doc);
99
- setHasUnsavedChanges(checkForChanges(doc, originalDoc));
100
- }}
101
- onAvailableTagsChange={handleAvailableTagsChange}
102
- onProjectFieldsChange={handleProjectFieldsChange}
103
- onSave={handleSaveProperty}
104
- />
105
- </div>
106
- )}
107
- </main>
108
-
109
- {/* ファイルブラウザ */}
110
- <FileBrowser
111
- isOpen={isFileBrowserOpen}
112
- currentPath={rootPath}
113
- multiSelect={true}
114
- filterJsonOnly={true}
115
- onSelect={(filePaths) => {
116
- handleSelectConfigFiles(filePaths);
117
- setIsFileBrowserOpen(false);
118
- }}
119
- onClose={() => setIsFileBrowserOpen(false)}
120
- />
121
-
122
- {/* エクスポートダイアログ */}
123
- <ExportDialog
124
- isOpen={isExportDialogOpen}
125
- onClose={() => setIsExportDialogOpen(false)}
126
- onExport={handleExport}
127
- currentSettings={exportSettings}
128
- rootPath={rootPath}
129
- />
130
-
131
- {/* トースト通知 */}
132
- <ToastContainer toasts={toasts} onRemove={removeToast} />
133
- </div>
134
- );
135
- }