BikeControl (SwiftControl)
Use Zwift Click, Zwift Play, Shimano Di2, or any Bluetooth controller with MyWhoosh, Rouvy, Zwift, and more. Free to try on iOS, Android, Windows, and macOS.
ตารางคะแนน โปรแกรมการแข่งขัน และสถิติผู้เล่นของ Artist FC
Translation pending
Sports & fitnessGitHub @ThadDevonixOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗ระบบจัดการลีกฟุตบอล — หน้าบ้านสำหรับผู้ชม และหลังบ้านสำหรับผู้ดูแลกับกรรมการ
เป็นโปรเจกต์เดียว (Next.js) หน้าบ้านกับหลังบ้านใช้ฐานข้อมูลและ data model ชุดเดียวกัน
npm install
npm run db:reset # สร้างฐานข้อมูล + ใส่ข้อมูลตัวอย่าง (10 ทีม 160 นักเตะ 45 นัด)
npm run dev
npm run dev ผูกกับทุก network interface อยู่แล้ว (next dev -H 0.0.0.0)
หา IP ของเครื่องแล้วเปิดจากมือถือได้เลย
ipconfig getifaddr en0 # เช่น 192.168.1.40
แล้วเข้า http://<IP>:3000 จากมือถือ
ถ้าเข้าไม่ได้ ให้เช็กว่า macOS ไม่ได้บล็อกไว้ที่ System Settings → Network → Firewall (ปิด หรืออนุญาต node)
| สิทธิ์ | อีเมล | รหัสผ่าน |
|---|---|---|
| ผู้ดูแลระบบ | [email protected] | admin1234 |
| กรรมการ | [email protected] | referee1234 |
เปลี่ยนรหัสผ่านและ
AUTH_SECRETใน.envก่อนขึ้นใช้งานจริงเสมอ
สีทั้งหมดมาจากโลโก้ Artist FC
| สี | ค่า | ใช้ที่ไหน |
|---|---|---|
| ส้ม | #F25C05 | ปุ่มหลัก แท็บที่เลือก ลิงก์ hover |
| ดำ | #0D0D0D | พื้นหลังโหมดมืด / ตัวอักษรโหมดสว่าง |
| ขาวนวล | #F5F3F4 | พื้นหลังโหมดสว่าง / ตัวอักษรโหมดมืด |
พื้นหลังสลับขาว/ดำตามเวลาประเทศไทยอัตโนมัติ
06:00–17:59 น. → พื้นขาว18:00–05:59 น. → พื้นดำธีมคำนวณจากฝั่งเซิร์ฟเวอร์ตั้งแต่ HTML แรก หน้าเว็บจึงไม่กะพริบตอนโหลด และใช้เวลาไทยเสมอไม่ว่าเครื่องผู้ใช้จะตั้ง timezone ไว้ยังไง
ปุ่มรูปนาฬิกามุมขวาบนกดสลับได้: ตามเวลาไทย → สว่าง → มืด → ตามเวลาไทย (จำค่าไว้ในเครื่องผู้ใช้) เปิดหน้าค้างไว้ข้ามเวลา ระบบจะเปลี่ยนธีมให้เองภายใน 1 นาที
แก้เวลาตัดได้ที่ DAY_START / NIGHT_START ใน src/lib/theme.ts
ไฟล์โลโก้: src/assets/artist-fc.png (ใช้เป็น favicon ด้วยผ่าน src/app/icon.png)
ออกแบบให้ใช้ได้ตั้งแต่จอ 320px (iPhone SE) ขึ้นไป ไม่มีการเลื่อนแนวนอนทั้งหน้า
ตารางคะแนน ซ่อนคอลัมน์ทีละชั้นตามความกว้างจอ แทนการบีบให้เลื่อนซ้ายขวา
| ความกว้าง | คอลัมน์ที่เห็น |
|---|---|
| < 640px | อันดับ · สโมสร · แข่ง · ต่าง · แต้ม |
| ≥ 640px | + ชนะ เสมอ แพ้ |
| ≥ 768px | + ได้ เสีย |
| ≥ 1024px | + ฟอร์ม 5 นัดล่าสุด |
หน้าบันทึกผล (/admin/matches) เปลี่ยนเป็นการ์ดบนจอเล็ก เพราะกรรมการใช้มือถือกรอกผลข้างสนาม
ตารางแบบเดิมจะโผล่เมื่อจอกว้าง ≥ 768px
ปุ่มบนแถบหัวเรื่อง ย่อเป็นไอคอนขนาด 36px บนมือถือ (ดูหน้าเว็บ / สลับธีม / ออกจากระบบ)
ตารางอื่น ๆ ซ่อนคอลัมน์รองแล้วย้ายข้อมูลสำคัญไปอยู่ใต้ชื่อแทน และยังซูมด้วยนิ้วได้ปกติ (ไม่ได้ล็อก user-scalable)
| ความสามารถ | ผู้ดูแลระบบ | กรรมการ |
|---|---|---|
| ดูหน้าเว็บ | ✓ | ✓ |
| บันทึกผลนัดที่ตัวเองเป็นผู้ตัดสิน | ✓ | ✓ |
| บันทึกผลนัดอื่น | ✓ | — |
| อนุมัติ / ตีกลับผล | ✓ | — |
| จัดการฤดูกาล สโมสร นักเตะ ผู้ใช้ | ✓ | — |
| ดูประวัติการแก้ไข | ✓ | — |
ขั้นตอนบันทึกผล: กรรมการกรอกสกอร์ → สถานะ รออนุมัติ (ยังไม่นับคะแนน) → ผู้ดูแลอนุมัติ → สถานะ จบแล้ว และตารางคะแนนขยับ ถ้าผู้ดูแลกรอกเอง จะถือว่าอนุมัติทันที
prisma/schema.prisma นิยามข้อมูล
src/
lib/ ตรรกะบริสุทธิ์ — ไม่แตะ DB ไม่แตะ React (เทสต์ได้ทันที)
standings.ts คำนวณตารางคะแนน + กฎตัดสินคะแนนเท่ากัน
fixtures.ts สร้างตารางแข่งแบบพบกันหมด
theme.ts ธีมขาว/ดำตามเวลาไทย
format.ts วันที่ เวลา ตัวเลข
labels.ts คำภาษาไทยของค่าคงที่ทุกตัว
server/ ทุกอย่างที่แตะฐานข้อมูลและ session
db.ts Prisma client ตัวเดียวของแอป
auth.ts session + รหัสผ่าน + audit log
guards.ts กฎว่าใครแก้อะไรได้ (จุดเดียวของทั้งระบบ)
validation.ts zod schema ของทุกฟอร์ม
queries/ อ่านข้อมูล แยกตามโดเมน
actions/ เขียนข้อมูล แยกตามโดเมน
components/ UI ที่ใช้ซ้ำ
app/
(public)/ หน้าบ้าน
admin/login/ หน้าเข้าสู่ระบบ
admin/(dash)/ หลังบ้าน (layout บังคับล็อกอินให้อัตโนมัติ)
scripts/ ชุดทดสอบ
ชั้นบนเรียกชั้นล่างได้อย่างเดียว และมีกฎ ESLint บังคับไว้จริง —
src/lib ห้าม import @/server, หน้าเพจห้ามเรียก db ตรง ๆ
📖 รายละเอียดว่า "จะแก้เรื่องนี้ ต้องไปไฟล์ไหน" อยู่ที่ ARCHITECTURE.md
ตารางคะแนน นับเฉพาะนัดสถานะ FINISHED เท่านั้น
แต้ม ตั้งค่าได้ต่อฤดูกาล (ค่าเริ่มต้น ชนะ 3 / เสมอ 1 / แพ้ 0)
เมื่อคะแนนเท่ากัน เลือกลำดับกฎเองได้ที่ /admin/seasons — ผลต่างประตู, ประตูได้, ผลการเจอกันเอง, จำนวนนัดที่ชนะ, เสียประตูน้อยกว่า, ประตูในเกมเยือน
ตารางแข่ง สร้างด้วย circle method — ทุกทีมเจอกันครบ ไม่มีทีมไหนแข่งซ้อนในนัดเดียวกัน จำนวนทีมเป็นเลขคี่จะมี 1 ทีมได้พักในแต่ละนัด เลือกได้ว่าเจอกันรอบเดียวหรือเหย้า–เยือน
npm run typecheck
npm run lint
npm run test # ต้องเปิด npm run dev ไว้อีกหน้าต่างหนึ่ง
| คำสั่ง | ทดสอบอะไร |
|---|---|
test:logic | ตารางคะแนนและตัวสร้างตารางแข่ง (4–20 ทีม) |
test:theme | ธีมสลับตามเวลาไทยครบ 24 ชั่วโมง |
test:workflow | ผลรออนุมัติไม่ถูกนับ และคะแนนขยับถูกต้องเมื่ออนุมัติ |
test:pages | ทุกหน้าขึ้นถูกต้องตามสิทธิ์ |
test:responsive | ทุกหน้าไม่ล้นจอที่ 320px และตั้ง viewport ถูกต้อง |
test:login | เข้าสู่ระบบ รหัสผ่านผิด และ session ปลอม |
test:flow | กรรมการกรอกผล → แอดมินอนุมัติ → ตารางคะแนนขยับ (ผ่าน HTTP จริง) |
ชุดทดสอบคืนค่าข้อมูลกลับสภาพเดิมทุกครั้ง
ใช้ PostgreSQL (เช่น Neon ผ่าน Vercel Storage) ทั้งตอน dev และ production
.env ให้มี DATABASE_URL (pooled) และ DATABASE_URL_UNPOOLED (ต่อตรง ใช้กับ migration)npx prisma migrate dev --name init แล้ว npm run db:seedDATABASE_URL, DATABASE_URL_UNPOOLED, AUTH_SECRET — vercel.json จะรัน prisma migrate deploy ก่อน next build ให้อัตโนมัติก่อน deploy อย่าลืมตั้ง AUTH_SECRET เป็นค่าสุ่ม:
openssl rand -base64 32