diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/.github/README.md b/.github/README.md deleted file mode 100644 index 58beeac..0000000 --- a/.github/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# Getting Started with Create React App - -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). - -## Available Scripts - -In the project directory, you can run: - -### `npm start` - -Runs the app in the development mode.\ -Open [http://localhost:3000](http://localhost:3000) to view it in your browser. - -The page will reload when you make changes.\ -You may also see any lint errors in the console. - -### `npm test` - -Launches the test runner in the interactive watch mode.\ -See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. - -### `npm run build` - -Builds the app for production to the `build` folder.\ -It correctly bundles React in production mode and optimizes the build for the best performance. - -The build is minified and the filenames include the hashes.\ -Your app is ready to be deployed! - -See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. - -### `npm run eject` - -**Note: this is a one-way operation. Once you `eject`, you can't go back!** - -If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. - -Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. - -You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. - -## Learn More - -You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). - -To learn React, check out the [React documentation](https://reactjs.org/). - -### Code Splitting - -This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) - -### Analyzing the Bundle Size - -This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) - -### Making a Progressive Web App - -This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) - -### Advanced Configuration - -This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) - -### Deployment - -This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) - -### `npm run build` fails to minify - -This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..90676b9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,22 @@ +name: CI + +on: + pull_request: + branches: [develop, prod] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: npm + + - run: npm ci + + - run: npm run lint + + - run: npm run build diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..ed82283 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,43 @@ +name: Deploy to ic-gr.net + +on: + push: + branches: [prod] + workflow_dispatch: + +permissions: + id-token: write + contents: read + +concurrency: + group: deploy-prod + cancel-in-progress: false + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: npm + + - run: npm ci + + - run: npm run build + + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::058264181659:role/github-actions-ic-gr-deploy + aws-region: ap-northeast-1 + + - name: Sync to S3 + run: aws s3 sync out/ s3://ic-gr.com/ --delete + + - name: Invalidate CloudFront cache (ic-gr.net) + run: | + aws cloudfront create-invalidation \ + --distribution-id EHFD30ZL5XZ0U \ + --paths "/*" diff --git a/.gitignore b/.gitignore index 4d29575..a4ef5a1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,13 @@ # testing /coverage -# production -/build +# next.js +/.next/ +/out/ + +# typescript +*.tsbuildinfo +next-env.d.ts # misc .DS_Store diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20 diff --git a/CLAUDE.md b/CLAUDE.md index f6f0ad8..5f53cc4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,92 +1,117 @@ -# neko — Ic-Growth コーポレートサイト +# ic-gr-website — Ic-Growth コーポレートサイト -Create React App 製の SPA。本番は AWS S3 + CloudFront で `https://www.ic-gr.net/` に公開。 +Next.js 15 (App Router) + React 19 + TypeScript + Tailwind CSS v4 製の静的サイト。`https://www.ic-gr.net/` で公開。 + +> 旧称 `neko`。リポジトリ名は `ic-gr-website` にリネーム済み(GitHub の自動リダイレクトで旧 URL も一定期間有効)。 ## 開発コマンド ```bash +nvm use # .nvmrc に従って Node 20 を選択 npm install -npm start # http://localhost:3000 -npm run build # build/ に成果物を出力 -npm test +npm run dev # http://localhost:3000 +npm run build # next build (static export → out/) +npm run lint ``` -## デプロイ(本番: ic-gr.net) +## デプロイ + +`prod` ブランチへの push で GitHub Actions が自動デプロイする(手動操作は不要)。 + +``` +develop ← 機能ブランチからの PR を集約 + │ + ▼ + prod ← push されると本番デプロイ +``` -参考記事: https://qiita.com/ushi_osushi/items/a32d7b710567c2313faa (S3+CloudFront+Route53+ACM の手動構築ガイド。CI/CDは無く手動デプロイ) +ステージング環境は存在しない。`develop` で動作確認後にそのまま `prod` へ進める。 -AWS プロファイル: `ic-gr`(アカウント `058264181659`) +ワークフロー: +- `.github/workflows/ci.yml` — PR 時に `npm run lint` + `npm run build` を実行 +- `.github/workflows/deploy.yml` — `prod` push をトリガに `next build` → `aws s3 sync out/` → CloudFront invalidation -```bash -# 1. ビルド(相対パスで出すため PUBLIC_URL を上書き) -PUBLIC_URL=. npm run build +GitHub Actions は OIDC で IAM Role `arn:aws:iam::058264181659:role/github-actions-ic-gr-deploy` を assume するため、リポジトリに AWS シークレットは持たない。 -# 2. S3 同期(バケットは ap-northeast-1 / 非公開・OAC経由) -aws --profile ic-gr s3 sync build/ s3://ic-gr.com/ --delete +### 緊急時の手動デプロイ(フォールバック) -# 3. CloudFront キャッシュ無効化(ic-gr.net 用) +ローカルから `aws --profile ic-gr` で同じことを実行できる。 + +```bash +npm ci +npm run build +aws --profile ic-gr s3 sync out/ s3://ic-gr.com/ --delete aws --profile ic-gr cloudfront create-invalidation \ --distribution-id EHFD30ZL5XZ0U --paths "/*" ``` -### インフラ構成(AWS 上の実体) +## インフラ構成(AWS 上の実体) | リソース | 値 | |---|---| -| S3 バケット | `ic-gr.com`(ap-northeast-1、非公開、OAC からのみ `s3:GetObject` 許可) | +| AWS アカウント | `058264181659`(CLI プロファイル `ic-gr`) | +| S3 バケット | `ic-gr.com`(ap-northeast-1、非公開、CloudFront OAC 経由のみ `s3:GetObject` 許可) | | CloudFront(本番) | `EHFD30ZL5XZ0U` / `d2sot6ky3ie96o.cloudfront.net` — alias: `ic-gr.net`, `www.ic-gr.net`, `*.ic-gr.net` | -| CloudFront(旧/併設) | `E3CUYP7CXV3V06` / `d16tpwwtsnlv00.cloudfront.net` — alias: `ic-gr.com`, `www.ic-gr.com`, `*.ic-gr.com` | +| CloudFront(旧 `.com` 系) | `E3CUYP7CXV3V06` / `d16tpwwtsnlv00.cloudfront.net` — alias: `ic-gr.com`, `www.ic-gr.com`, `*.ic-gr.com`(同じ S3 を origin) | | Route53 ホストゾーン | `ic-gr.net.`(A レコードで CloudFront にエイリアス、ワイルドカードあり) | +| デプロイ用 IAM Role | `github-actions-ic-gr-deploy`(GitHub OIDC で `repo:angurodon/ic-gr-website:ref:refs/heads/prod` のみ信頼) | | Default Root Object | `index.html` | -`.com` ドメインの CloudFront も同じ S3 バケットを向いているので、`s3 sync` 後は両方の invalidation を打つかどうか判断する。 - -### `package.json` の `homepage` に注意 - -`homepage` が `https://angurodon.github.io/neko` のままになっている(旧 GitHub Pages 配信の名残)。 -そのままビルドすると CRA がアセットを `/neko/static/...` 配下に出力し、ic-gr.net では 404 になる。 -**AWS デプロイ時は必ず `PUBLIC_URL=.` か `homepage: "."` で上書きしてビルドする**こと。 -S3 上の `index.html` は実際に相対パス(`./static/js/...`)でビルドされている。 - -### `npm run deploy` は AWS 用ではない - -`package.json` の `deploy` スクリプトは `gh-pages -d build`(GitHub Pages 用)。AWS デプロイには使わない。 +`.com` ドメイン側の CloudFront には今回のデプロイでは invalidation を打っていないため、`*.ic-gr.com` でも即時反映したい場合は手動で `--distribution-id E3CUYP7CXV3V06` の invalidation を実行する。 -## ルーティング上の既知の制約 +### SPA 直リンク問題は解消済み -- `App.js` は `react-router-dom` の `BrowserRouter` を使用。ルート: `/`, `/neko`, `/overview`, `/company`, `/privacy`。 -- CloudFront のカスタムエラーレスポンス未設定。`/overview` 等の**直リンク(リロード)は S3 から 403/404 が返る**。現状はヘッダのリンク経由でのみ遷移可能。 -- 直リンクを動かすには CloudFront に `403/404 → /index.html (200)` の Custom Error Response を追加する必要がある。 +旧 CRA では CloudFront に Custom Error Response 未設定だったため `/overview` などのリロードで 403 を返していたが、Next.js の static export + `trailingSlash: true` で各ルートが `out/overview/index.html` として生成されるため、ハードリロードでも 200 が返る。 ## ディレクトリ構成 ``` -src/ -├── App.js # ルーティング -├── index.js / index.css # エントリ -├── ScrollToTop.js # ルート遷移時のスクロール初期化 -├── assets/ # 画像(ロゴ、サービス紹介画像) -├── components/ -│ ├── HeaderComponents/ # ヘッダ(ハンバーガーメニュー、外部 Google フォームへのリンク) -│ ├── FooterComponents/ -│ ├── HomepageComponents/ # `/` と `/neko` の本体。SectionComponent1 + Backup + Consult を組み合わせる -│ ├── SectionComponent1/ # トップのヒーロー部 -│ ├── BackupComponents/ # サービス: バックアップ系 -│ ├── ConsultComponents/ # サービス: コンサル系 -│ ├── OverviewComponents/ # /overview 事業概要 -│ ├── CompanyComponents/ # /company 会社概要 -│ └── PrivacyComponents/ # /privacy -└── Gabage/ # 旧コンポーネント(typo: Garbage ではなく Gabage)。SystemSupport / BusinessSupport / MAS。App.js でコメントアウト中。削除可否を確認してから消すこと +ic-gr-website/ +├── app/ +│ ├── layout.tsx # ルートレイアウト(Header + Footer + ScrollToTop + metadata) +│ ├── page.tsx # / (SectionComponent1 + Backup + Consult) +│ ├── overview/page.tsx # /overview (事業概要 + 3 セクション) +│ ├── company/page.tsx # /company (会社概要テーブル) +│ ├── privacy/page.tsx # /privacy (個人情報保護方針) +│ ├── sitemap.ts # ビルド時に sitemap.xml を生成 +│ ├── robots.ts # ビルド時に robots.txt を生成 +│ ├── globals.css # Tailwind v4 + CSS 変数(ブランドカラー / フォント) +│ └── components/ +│ ├── Header.tsx # 'use client' (ハンバーガー開閉) +│ ├── Footer.tsx +│ ├── ScrollToTop.tsx # 'use client' (usePathname でスクロールリセット) +│ ├── SectionComponent1.tsx +│ ├── Backup.tsx # トップの3カード(/overview#... に遷移) +│ └── Consult.tsx # 電話相談バナー +├── public/ +│ ├── favicon.ico # ※ Ic-Growth ブランドの ico に差し替え予定 +│ ├── apple-touch-icon.png # ※ ブランド資産入手後に追加 +│ ├── logo192.png / logo512.png +│ ├── manifest.webmanifest +│ └── images/ # next/image で参照する画像群 +├── next.config.ts # output: 'export', trailingSlash: true, images.unoptimized: true +├── tsconfig.json +├── postcss.config.mjs # @tailwindcss/postcss +├── .nvmrc # 20 +└── .github/workflows/ + ├── ci.yml + └── deploy.yml ``` -問い合わせは外部 Google Form(Header.jsx 内に URL ハードコード)。 +問い合わせは外部 Google Form(`Header.tsx` / `Footer.tsx` 内に URL ハードコード)。 -## 未使用の依存関係 +## ブランド資産(未確定) -`i18next` 系・`react-i18next` 系・`react-scroll` 系が `package.json` にあるがコード側で `import` されていない。多言語対応や smooth scroll を再導入する予定が無いなら、`npm uninstall` で整理して構わない。 +旧 CRA 版から失われたタイトル `Ic-Growth` と独自 favicon は、ユーザーから素材を受領後に以下を差し替える: +- `public/favicon.ico`(マルチサイズ ICO 推奨: 16/32/48) +- `public/apple-touch-icon.png` (180×180) +- `public/logo192.png` (192×192) +- `public/logo512.png` (512×512) +タイトルとメタ description は `app/layout.tsx` で定義済み。 ## ブランチ運用 -- 本流: `main` -- 機能別ブランチ(`form`, `phone`, `footer`, `route`, `sumaho`, `fix-1` 等)を切って PR → squash/merge する流れ。 -- `gh-pages` ブランチは旧 GitHub Pages 配信の成果物ブランチ。AWS 配信に移行済みのため通常触らない。 +- `develop` (デフォルト): 機能ブランチからの PR を集約 +- `prod`: push されると本番デプロイ +- 旧 `main` / `gh-pages` ブランチは過去の遺物。ステージングは持たない運用に変更したため `main` は使わない +- 機能ブランチは `feature/` 命名で `develop` から切る diff --git a/README.md b/README.md new file mode 100644 index 0000000..ad96669 --- /dev/null +++ b/README.md @@ -0,0 +1,215 @@ +# ic-gr-website + +Ic-Growth コーポレートサイト (`https://www.ic-gr.net/`) のソースコード。 + +Next.js 15 (App Router) + React 19 + TypeScript + Tailwind CSS v4 製の静的サイト。`next build` で静的書き出しを行い、AWS S3 + CloudFront から配信する。 + +## 開発 + +```bash +nvm use # .nvmrc に従って Node 20 +npm install +npm run dev # http://localhost:3000 +npm run build # next build → out/ +npm run lint +``` + +## ブランチ運用 + +``` +develop ← 機能ブランチからの PR を集約(デフォルト) + │ + ▼ + prod ← push されると本番デプロイ +``` + +機能ブランチは `feature/` 命名で `develop` から切る。 +ステージング環境は存在しないため、`develop` での動作確認後にそのまま `prod` へ進める。 + +--- + +## 本番デプロイ + +`prod` ブランチへの push で GitHub Actions が自動デプロイする。手動操作は不要。 + +### 手順(推奨:PR 経由) + +1. `develop` 上で動作確認(`npm run dev` でローカル確認、必要なら機能ブランチを develop に取り込む) +2. `develop → prod` の PR を作成・マージ(**push された瞬間に本番デプロイが走る**) +3. Actions タブで `Deploy to ic-gr.net` ジョブが完走するのを確認 +4. `https://www.ic-gr.net/` を全ページ + 直リンクハードリロードで確認 + +### 手順(緊急時:CLI から直接) + +`prod` への push が直接走るため取り扱い注意。 + +```bash +git checkout prod && git merge --no-ff develop && git push # ← ここでデプロイ起動 +``` + +### ワークフロー + +| ファイル | トリガ | やること | +|---|---|---| +| `.github/workflows/ci.yml` | `develop` / `prod` への PR | `npm run lint` + `npm run build` | +| `.github/workflows/deploy.yml` | `prod` への push(または手動 `workflow_dispatch`) | `next build` → `aws s3 sync out/` → CloudFront invalidation | + +GitHub Actions は **OIDC で IAM Role を assume する**ので、リポジトリに長期 AWS 認証情報を置かない。仕組みの詳細は [`doc/deploy-architecture.md`](doc/deploy-architecture.md) を参照。 + +### 失敗時の挙動 + +- **CI ジョブが赤** → コードまたは型の問題。原因を直して PR を更新する +- **deploy ジョブが赤(assume role 失敗)** → IAM Role の信頼ポリシーがリポジトリ名・ブランチを正しく指しているか確認([トラブルシュート](#災害復旧--再構築)) +- **deploy ジョブが赤(s3 sync / invalidation 失敗)** → 権限ポリシー、もしくは S3 / CloudFront のリソース ID 不一致を疑う +- **デプロイは完走したのに反映されない** → CloudFront のキャッシュ。invalidation が走っているはずだが、ブラウザ側のキャッシュも疑う(DevTools → Disable cache)。`E3CUYP7CXV3V06`(`*.ic-gr.com` 系)には invalidation を撃っていない + +### 緊急時の手動デプロイ(フォールバック) + +ローカルから AWS CLI で同じ操作を実行できる。 + +```bash +npm ci +npm run build +aws --profile ic-gr s3 sync out/ s3://ic-gr.com/ --delete +aws --profile ic-gr cloudfront create-invalidation \ + --distribution-id EHFD30ZL5XZ0U --paths "/*" +``` + +`ic-gr.com` 側 (`*.ic-gr.com`) も即時反映したい場合は、上記の invalidation を `--distribution-id E3CUYP7CXV3V06` でも追加で実行する。 + +--- + +## AWS インフラ + +| リソース | 値 | +|---|---| +| AWS アカウント | `058264181659`(ローカル CLI プロファイル `ic-gr`) | +| リージョン | `ap-northeast-1`(CloudFront / ACM のみ `us-east-1`) | +| S3 バケット | `ic-gr.com`(非公開、CloudFront OAC 経由のみ `s3:GetObject` 許可) | +| CloudFront(本番) | `EHFD30ZL5XZ0U` / `d2sot6ky3ie96o.cloudfront.net` — alias: `ic-gr.net`, `www.ic-gr.net`, `*.ic-gr.net` | +| CloudFront(旧 `.com` 系) | `E3CUYP7CXV3V06` / `d16tpwwtsnlv00.cloudfront.net` — alias: `ic-gr.com`, `www.ic-gr.com`, `*.ic-gr.com`(同じ S3 を origin) | +| Route53 ホストゾーン | `ic-gr.net.`(A レコードで CloudFront にエイリアス、ワイルドカードあり) | +| デプロイ用 IAM Role | `github-actions-ic-gr-deploy`(GitHub OIDC で `repo:angurodon/ic-gr-website:ref:refs/heads/prod` のみ信頼) | +| Default Root Object | `index.html` | + +`output: 'export'` + `trailingSlash: true` により、各ルートが `out//index.html` で生成される。CloudFront の Custom Error Response 設定なしでハードリロードでも 200 が返る。 + +> **AWS 側の初回セットアップは完了済み**(OIDC Provider と IAM Role `github-actions-ic-gr-deploy` は作成済み)。日常運用では追加の AWS 操作は不要。再構築が必要になった場合のみ [災害復旧 / 再構築](#災害復旧--再構築) を参照。 + +--- + +## 災害復旧 / 再構築 + +AWS リソースを誤って消したり別アカウントへ引越す際の手順。日常運用では使わない。 + +### OIDC Provider と IAM Role の再作成 + +`aws --profile ic-gr` で以下を順に実行する。 + +```bash +# 1. OIDC Provider +aws --profile ic-gr iam create-open-id-connect-provider \ + --url https://token.actions.githubusercontent.com \ + --client-id-list sts.amazonaws.com \ + --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 + +# 2. IAM Role(trust-policy.json と role-policy.json を作ってから) +aws --profile ic-gr iam create-role \ + --role-name github-actions-ic-gr-deploy \ + --assume-role-policy-document file://trust-policy.json + +aws --profile ic-gr iam put-role-policy \ + --role-name github-actions-ic-gr-deploy \ + --policy-name deploy \ + --policy-document file://role-policy.json +``` + +`trust-policy.json`(GitHub Actions に AssumeRole を許可する条件): + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::058264181659:oidc-provider/token.actions.githubusercontent.com" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" + }, + "StringLike": { + "token.actions.githubusercontent.com:sub": "repo:angurodon/ic-gr-website:ref:refs/heads/prod" + } + } + } + ] +} +``` + +`role-policy.json`(このロールが実行できるアクション): + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": ["s3:ListBucket"], + "Resource": "arn:aws:s3:::ic-gr.com" + }, + { + "Effect": "Allow", + "Action": ["s3:PutObject", "s3:DeleteObject", "s3:GetObject"], + "Resource": "arn:aws:s3:::ic-gr.com/*" + }, + { + "Effect": "Allow", + "Action": ["cloudfront:CreateInvalidation"], + "Resource": "arn:aws:cloudfront::058264181659:distribution/EHFD30ZL5XZ0U" + } + ] +} +``` + +### 切り分けのポイント + +deploy ジョブが落ちた時の典型的な原因: + +- **AssumeRole 失敗**: 信頼ポリシーの `sub` がリポジトリ名・ブランチ名と一致していない(リネーム後など) +- **S3 / CloudFront 操作で `AccessDenied`**: 権限ポリシーで指定したリソース ARN が違う +- **OIDC Provider 認証エラー**: GitHub 側のキー更新でサムプリントが古くなった可能性 + +--- + +## ディレクトリ構成 + +``` +ic-gr-website/ +├── app/ +│ ├── layout.tsx # ルートレイアウト(Header + Footer + ScrollToTop + metadata) +│ ├── page.tsx # / (SectionComponent1 + Backup + Consult) +│ ├── overview/page.tsx # /overview +│ ├── company/page.tsx # /company +│ ├── privacy/page.tsx # /privacy +│ ├── sitemap.ts / robots.ts # ビルド時に sitemap.xml / robots.txt を生成 +│ ├── globals.css # Tailwind v4 + CSS 変数 +│ └── components/ +│ ├── Header.tsx # 'use client'(ハンバーガーメニュー) +│ ├── Footer.tsx +│ ├── ScrollToTop.tsx # 'use client'(usePathname でスクロールリセット) +│ ├── SectionComponent1.tsx +│ ├── Backup.tsx +│ └── Consult.tsx +├── public/ +│ ├── favicon.ico / logo192.png / logo512.png +│ ├── manifest.webmanifest +│ └── images/ # next/image で参照する画像 +├── next.config.ts # output: 'export', trailingSlash: true +├── .github/workflows/ # ci.yml, deploy.yml +└── CLAUDE.md # AI アシスタント向けプロジェクトメモ +``` + +問い合わせは外部 Google Form(`Header.tsx` / `Footer.tsx` 内に URL ハードコード)。 diff --git a/app/company/page.tsx b/app/company/page.tsx new file mode 100644 index 0000000..866ed73 --- /dev/null +++ b/app/company/page.tsx @@ -0,0 +1,125 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "会社概要", + description: + "株式会社 Ic-Growth の会社概要。所在地、設立、代表者、事業内容などをご案内します。", +}; + +const rows: { label: string; content: React.ReactNode }[] = [ + { + label: "会社名", + content: ( + <> + アイシイグロウス + 株式会社 Ic-Growth + + ), + }, + { label: "法人番号", content: "8011401022351" }, + { + label: "住所", + content: ( + <> + 本社: +
+ 〒174-0056 +
+ 東京都板橋区志村1丁目30番15号 +
+
+ Tel:03-3960-3311 + + ), + }, + { label: "設立", content: "令和2年(2020年)1月22日" }, + { label: "代表者", content: "前田 剛" }, + { label: "資本金", content: "800千円(2024年月日現在)" }, + { + label: "事業内容", + content: ( + <> + 経理支援 +
+ 経理システムの導入支援 +
+ 経理分析 + + ), + }, + { + label: "弊社サービス", + content: ( + <> + 【経理システム導入支援】 +
+ ・勤怠管理システム導入支援 +
+ ・給与計算システム導入支援 +
+ ・会計システム導入支援 +
+ ・請求書発行システム導入支援 +
+ ・経費精算システム導入支援 +
+ ・証憑管理システム導入支援 +
+ ・証憑データ化システム導入支援 +
+
+ 【経理支援】 +
+ ・会計データ作成業務 +
+ ・経理指導 +
+ ・請求書発行業務 +
+ ・受取請求書等整理業務 +
+ ・給与計算業務 +
+
+ 【経営支援】 +
+ ・連絡ツール導入支援 +
+ ・その他システムのご案内 +
+ ・MAS(経営アドバイザリーサービス) +
+
+ 【その他】 +
+ ・生命保険業務 +
+ ・相続時資料回収業務 + + ), + }, +]; + +export default function CompanyPage() { + return ( +
+

+ 会 社 概 要 +

+ + + {rows.map((row) => ( + + + + + ))} + +
+ {row.label} + + {row.content} +
+
+ ); +} diff --git a/app/components/Backup.tsx b/app/components/Backup.tsx new file mode 100644 index 0000000..00ff997 --- /dev/null +++ b/app/components/Backup.tsx @@ -0,0 +1,58 @@ +import Link from "next/link"; +import Image from "next/image"; + +const cards = [ + { + href: "/overview#system-support", + src: "/images/backup_system.png", + alt: "経理システムの導入支援", + title: "経理システムの導入支援", + }, + { + href: "/overview#business-support", + src: "/images/backup_ec.png", + alt: "経理支援アイコン", + title: "経理支援", + }, + { + href: "/overview#msa-support", + src: "/images/MAS.png", + alt: "MAS", + title: "経営アドバイザリーサービス", + }, +]; + +export default function Backup() { + return ( +
+

+ 事 業 概 要 +

+

+ 我々は下記サービスを導入支援いたします +

+
+ {cards.map((card) => ( + +
+ {card.alt} +
+

+ {card.title} +

+ + ))} +
+
+ ); +} diff --git a/app/components/Consult.tsx b/app/components/Consult.tsx new file mode 100644 index 0000000..d19995f --- /dev/null +++ b/app/components/Consult.tsx @@ -0,0 +1,34 @@ +import Image from "next/image"; + +export default function Consult() { + return ( +
+
+

+ 無料相談はこちらから +

+
+
+ + + 電話アイコン + + + + TEL:03-3960-3311 + + + +
+
+ ); +} diff --git a/app/components/Footer.tsx b/app/components/Footer.tsx new file mode 100644 index 0000000..a3d6c09 --- /dev/null +++ b/app/components/Footer.tsx @@ -0,0 +1,62 @@ +import Link from "next/link"; +import Image from "next/image"; + +const CONTACT_FORM_URL = + "https://docs.google.com/forms/d/e/1FAIpQLScEXuDiU9GfCsL2Q4nmK9En8xLd8UzVYR6B95K9IKwNAL6GTQ/viewform"; + +export default function Footer() { + return ( +
+
+
+ Ic-Growth ロゴ + +

+ 個人情報保護方針について +

+ +
+ +
+ +
+
+
+ ); +} diff --git a/app/components/Header.tsx b/app/components/Header.tsx new file mode 100644 index 0000000..8714e55 --- /dev/null +++ b/app/components/Header.tsx @@ -0,0 +1,102 @@ +"use client"; + +import Link from "next/link"; +import Image from "next/image"; +import { useState } from "react"; + +const CONTACT_FORM_URL = + "https://docs.google.com/forms/d/e/1FAIpQLScEXuDiU9GfCsL2Q4nmK9En8xLd8UzVYR6B95K9IKwNAL6GTQ/viewform"; + +export default function Header() { + const [isMenuOpen, setIsMenuOpen] = useState(false); + + const closeMenu = () => setIsMenuOpen(false); + const toggleMenu = () => setIsMenuOpen((open) => !open); + + return ( +
+
+ + Ic-Growth ロゴ + +
+ + {/* ハンバーガーアイコン (モバイル) */} + + + {/* ナビゲーション (デスクトップは inline、モバイルはサイドメニュー) */} + +
+ ); +} diff --git a/app/components/ScrollToTop.tsx b/app/components/ScrollToTop.tsx new file mode 100644 index 0000000..b3e00e2 --- /dev/null +++ b/app/components/ScrollToTop.tsx @@ -0,0 +1,14 @@ +"use client"; + +import { usePathname } from "next/navigation"; +import { useEffect } from "react"; + +export default function ScrollToTop() { + const pathname = usePathname(); + + useEffect(() => { + window.scrollTo(0, 0); + }, [pathname]); + + return null; +} diff --git a/app/components/SectionComponent1.tsx b/app/components/SectionComponent1.tsx new file mode 100644 index 0000000..4d2b42c --- /dev/null +++ b/app/components/SectionComponent1.tsx @@ -0,0 +1,35 @@ +import Image from "next/image"; + +export default function SectionComponent1() { + return ( +
+
+

+ 個人と企業の成長に貢献します! +
+ Contribute to the growth of individuals and companies +

+

+ 日本の近未来における厳しい環境化であっても +
+ 持続的成長を遂げるために +
+ 有限である経営資源(ヒト・モノ・カネ・時間)活用の最適化を図ることを使命とします。 +
+ 我々はこの使命を「会計をエネルギーに変換すること」で実現します。 +
+ 「Accounting Transformation」「AX」の実現を目指します。 +

+
+
+ Ic-Growth Logo +
+
+ ); +} diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..7f75ccf --- /dev/null +++ b/app/globals.css @@ -0,0 +1,29 @@ +@import "tailwindcss"; + +@theme { + --color-brand-primary: #0b5fff; + --color-brand-dark: #0b1736; + --color-brand-accent: #f5a623; + --font-family-sans: "Hiragino Kaku Gothic ProN", "Yu Gothic", "Meiryo", system-ui, sans-serif; +} + +html { + scroll-behavior: smooth; + scroll-padding-top: 90px; /* fixed header (75px) + 余白 */ +} + +html, +body { + font-family: var(--font-family-sans); + color: #1a1a1a; + background: #ffffff; +} + +body { + padding-top: 100px; /* fixed header の高さ分 */ +} + +a { + color: inherit; + text-decoration: none; +} diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 0000000..40452bb --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,49 @@ +import type { Metadata } from "next"; +import "./globals.css"; +import Header from "./components/Header"; +import Footer from "./components/Footer"; +import ScrollToTop from "./components/ScrollToTop"; + +const SITE_NAME = "Ic-Growth"; +const SITE_URL = "https://www.ic-gr.net"; +const SITE_DESCRIPTION = + "Ic-Growth はバックアップ・コンサルティングを軸に、企業の事業成長を支援する会社です。"; + +export const metadata: Metadata = { + metadataBase: new URL(SITE_URL), + title: { + default: SITE_NAME, + template: `%s | ${SITE_NAME}`, + }, + description: SITE_DESCRIPTION, + openGraph: { + type: "website", + locale: "ja_JP", + url: SITE_URL, + siteName: SITE_NAME, + title: SITE_NAME, + description: SITE_DESCRIPTION, + }, + icons: { + icon: "/favicon.ico", + apple: "/apple-touch-icon.png", + }, + manifest: "/manifest.webmanifest", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + +
+
{children}
+