From 1d7ab4b2b35a5f87a532d248ffdea25e03370f5a Mon Sep 17 00:00:00 2001 From: Last2014 Date: Wed, 16 Jul 2025 19:08:24 +0900 Subject: [PATCH] =?UTF-8?q?PeasForm=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- next.config.ts | 2 - package-lock.json | 141 +++++++++++++++++++++++++++++++ package.json | 2 + src/app/api/peasForm/route.ts | 25 ++++++ src/app/globals.css | 14 +++ src/app/peas/alpha-open/page.tsx | 130 ++++++++++++++++++++++++++++ src/lib/db.ts | 16 ++++ 8 files changed, 329 insertions(+), 3 deletions(-) create mode 100644 src/app/api/peasForm/route.ts create mode 100644 src/app/peas/alpha-open/page.tsx create mode 100644 src/lib/db.ts diff --git a/README.md b/README.md index 535b453..cd76b66 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # Last2014 -https://last2014.f5.si +https://last2014.com Last2014 Home Website diff --git a/next.config.ts b/next.config.ts index 1d77d4b..1f6f6ce 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,8 +1,6 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - output: "export", - distDir: process.env.DIST || "./out", images: { unoptimized: true, }, diff --git a/package-lock.json b/package-lock.json index fafa694..1c4aa88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,8 @@ "@types/next": "^9.0.0", "bulma": "^1.0.4", "date-fns": "^4.1.0", + "dotenv": "^17.2.0", + "mysql2": "^3.14.2", "next": "^15.3.3", "react": "^19.1.0", "react-dom": "^19.1.0", @@ -1813,6 +1815,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/aws-ssl-profiles": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", + "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/axe-core": { "version": "4.10.3", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", @@ -2190,6 +2201,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, "node_modules/detect-libc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", @@ -2213,6 +2233,18 @@ "node": ">=0.10.0" } }, + "node_modules/dotenv": { + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.0.tgz", + "integrity": "sha512-Q4sgBT60gzd0BB0lSyYD3xM4YxrXA9y4uBDof1JNYGzOXrQdQ6yX+7XIAqoFOGQFOTK1D3Hts5OllpxMDZFONQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -3033,6 +3065,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "license": "MIT", + "dependencies": { + "is-property": "^1.0.2" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -3260,6 +3301,18 @@ "node": ">= 0.4" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -3575,6 +3628,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "license": "MIT" + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -3889,6 +3948,12 @@ "dev": true, "license": "MIT" }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -3902,6 +3967,30 @@ "loose-envify": "cli.js" } }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/lru.min": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.2.tgz", + "integrity": "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg==", + "license": "MIT", + "engines": { + "bun": ">=1.0.0", + "deno": ">=1.30.0", + "node": ">=8.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wellwelwel" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -3966,6 +4055,38 @@ "dev": true, "license": "MIT" }, + "node_modules/mysql2": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.14.2.tgz", + "integrity": "sha512-YD6mZMeoypmheHT6b2BrVmQFvouEpRICuvPIREulx2OvP1xAxxeqkMQqZSTBefv0PiOBKGYFa2zQtY+gf/4eQw==", + "license": "MIT", + "dependencies": { + "aws-ssl-profiles": "^1.1.1", + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^5.2.1", + "lru.min": "^1.0.0", + "named-placeholders": "^1.1.3", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "license": "MIT", + "dependencies": { + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -4615,6 +4736,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, "node_modules/scheduler": { "version": "0.26.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", @@ -4634,6 +4761,11 @@ "node": ">=10" } }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -4843,6 +4975,15 @@ "node": ">=0.10.0" } }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/stable-hash": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", diff --git a/package.json b/package.json index 0db3f67..84a54a4 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "@types/next": "^9.0.0", "bulma": "^1.0.4", "date-fns": "^4.1.0", + "dotenv": "^17.2.0", + "mysql2": "^3.14.2", "next": "^15.3.3", "react": "^19.1.0", "react-dom": "^19.1.0", diff --git a/src/app/api/peasForm/route.ts b/src/app/api/peasForm/route.ts new file mode 100644 index 0000000..f0eebf6 --- /dev/null +++ b/src/app/api/peasForm/route.ts @@ -0,0 +1,25 @@ +import pool from "@/lib/db"; +import type { RowDataPacket } from "mysql2"; + +import { NextResponse, NextRequest } from "next/server"; + +export async function POST(request: NextRequest) { + const body = await request.json(); + const { uwuzunetUser, email } = body; + + if (!uwuzunetUser || !email) { + return NextResponse.json({ + status: "error", + error: "Body Required", + }); + } else { + await pool.execute( + "INSERT INTO `form` (`uwuzunetUser`, `email`) VALUES (?, ?)", + [uwuzunetUser, email], + ); + + return NextResponse.json({ + status: "success", + }) + } +} diff --git a/src/app/globals.css b/src/app/globals.css index f70ca38..94504af 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -44,3 +44,17 @@ main { flex: 1; padding: 1rem; } + +li { + width: fit-content; + margin: 0 auto; +} + +.box { + width: fit-content; + margin: 0 auto; +} + +.input { + width: 20rem; +} diff --git a/src/app/peas/alpha-open/page.tsx b/src/app/peas/alpha-open/page.tsx new file mode 100644 index 0000000..c56a5d1 --- /dev/null +++ b/src/app/peas/alpha-open/page.tsx @@ -0,0 +1,130 @@ +"use client"; + +import { Icon } from "@iconify/react"; +import Link from "next/link"; +import { useState } from "react"; + +export default function PeasAlphaOpen() { + const [Load, setLoad] = useState(false); + + const FormSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setLoad(true); + + try { + const req = await fetch("/api/peasForm", { + method: "POST", + body: JSON.stringify({ + uwuzunetUser: e.currentTarget.uwuzunetUser.value, + email: e.currentTarget.email.value, + }) + }); + + const res = await req.json(); + + if (res.status === "error") { + alert(`エラー: ${res.error}`); + } else { + alert("送信完了"); + } + } catch (err) { + alert(`通信エラー: ${err}`); + } finally { + setLoad(false); + } + }; + + return ( +
+ {Load && ( +
+ +
+ )} + +

Peas公式サーバー先行公開申請

+ +

募集期間:2025/07/16 19:00 - 2025/07/23 23:59:59

+ +

条件

+
    +
  • GIGAスクール端末での参加は不可
  • +
  • 13歳未満の場合は保護者の同意が必要
  • +
  • 利用規約・プライバシーポリシー・NDAへの同意が必要(これらは先行公開時に参加者へ送信)
  • +
  • 有効なメールアドレスが必要
  • +
  • サービスの開発・運営に害を与えない行動範囲での使用
  • +
  • 参加申請後での申請取り消しは不可(例外はよくありそうな質問2,3)
  • +
+ +

注意事項

+
    +
  • Last2014が必要な情報をメールで尋ねる可能性があります
  • +
  • この先行公開のやり取りはすべてメール上で行われ、Last2014はlast2014yh@yahoo.co.jpのメールアドレスを使用します
  • +
+ +

よくありそうな質問

+
+ Q1. フィルターがかかります。 +
+ A. GIGAスクール端末は先行公開への参加は拒否させていただきます。 +
+ その他のフィルターの場合は管理者に解除を申請してください。 +
+ +
+ Q2. 利用規約とプライバシーポリシー、NDAを教えてください。 +
+ A. 条件に記載されている通り先行公開時に電子メールで参加者へ送信させていただきます。 +
+ 確認後に同意いただけない場合は申請の取り消しが可能です。 +
+ Last2014まで折り返しメールをお願い致します。 +
+ (全員へ返信ではなくLast2014のみに返信してください) +
+ +
+ Q3. 申請取り消しの例外を教えてください。 +
+ A. Q2に記載されている通り、 +
+ 利用規約・プライバシーポリシー・NDAのいずれかに同意いただけない場合は +
+ 申請取り消しが可能です。 +
+ また、理由をLast2014に送信し承認された場合も申請取り消しが可能です。 +
+ +

フォーム

+ +
+ + + + + + + + + +
+
+ ); +} diff --git a/src/lib/db.ts b/src/lib/db.ts new file mode 100644 index 0000000..c9fc174 --- /dev/null +++ b/src/lib/db.ts @@ -0,0 +1,16 @@ +import { config } from "dotenv"; +config(); + +import mysql from "mysql2/promise"; + +const pool = mysql.createPool({ + host: process.env.databaseHost, + port: Number(process.env.databasePort), + user: process.env.databaseUser, + password: process.env.databasePassword, + database: process.env.databaseDB, + waitForConnections: true, + connectionLimit: 10, +}); + +export default pool;