Bài toán
Thương hiệu cần một trò chơi ngắn, vui để khách tham gia ngay tại sự kiện: khách để lại số điện thoại, chơi một lượt vài giây và nhận quà nếu thắng. Ban tổ chức cần theo dõi số lượt chơi, tỉ lệ thắng/thua theo từng sản phẩm và xuất danh sách để trao quà, chăm sóc sau sự kiện.
Chức năng chính
- Màn hình bắt đầu mang nhận diện Hanoimilk, nút "BẮT ĐẦU" có hiệu ứng thu hút.
- Nhập số điện thoại bằng bàn phím số trên màn hình, kiểm tra định dạng số Việt Nam (10 số, bắt đầu bằng 0) trước khi cho chơi.
- Chọn sản phẩm: sữa chua, sữa hộp, sữa tươi 100%.
- Gameplay "ghép hình": ảnh sản phẩm được cắt thành 4 mảnh A–B–C–D, xáo trộn có hoạt ảnh; người chơi chọn lại đúng thứ tự trong 10 giây có đồng hồ đếm ngược.
- Kết quả: màn hình BINGO với pháo giấy khi thắng; màn hình "Ôi, tiếc quá" khi sai hoặc hết giờ; nút chơi lại.
- Âm thanh: nhạc nền và hiệu ứng chạm/thắng/thua (Web Audio).
- Lưu kết quả an toàn: lượt chơi được đưa vào hàng đợi trong trình duyệt rồi đồng bộ lên server, nên không mất dữ liệu khi mạng chập chờn; API có chống CSRF (double-submit cookie); ghi nhận thông tin thiết bị truy cập.
- Dashboard ban tổ chức: thẻ KPI (tổng lượt chơi, thắng, thua, tỉ lệ thắng), biểu đồ theo ngày, tỉ lệ thắng/thua, sản phẩm được chọn, tỉ lệ thắng theo sản phẩm; nhật ký lượt chơi có tìm theo số điện thoại, phân trang; tự làm mới 30 giây/lần; tải file CSV.
Công nghệ
- Frontend: Vite + JavaScript thuần, CSS animation, tối ưu thao tác chạm (bỏ độ trễ 300 ms, chống "ghost click"), tự co giãn theo màn hình.
- Backend: Node.js + Express, lưu kết quả ra file CSV và log truy cập.
- Dashboard: Chart.js + chartjs-plugin-datalabels.
- Triển khai: Docker (multi-stage build), GitLab CI build và đẩy image.
Điểm ưu việt
- Gọn nhẹ, không cần cơ sở dữ liệu, chạy được trên một container nhỏ; dễ dựng nhanh cho từng sự kiện.
- Trải nghiệm cảm ứng mượt, thời gian chơi ngắn (10 giây) phù hợp đông khách tại điểm bán.
- Dữ liệu thu thập được dùng ngay: xem thống kê trực tiếp và xuất CSV để trao quà/chăm sóc khách.
- Có lớp bảo vệ cơ bản (CSRF, kiểm tra dữ liệu đầu vào) và hàng đợi offline chống mất lượt chơi.





