イクチオカップ

24時間限定アルバム

https://github.com/KeishiKanzaki/Aken

Next.js

TypeScript

React

CSS

HTML

24時間で閲覧ができなくなってしまうアルバムです。

Keishi Kanzaki

gcpsp923vm

推しアイデア

作ったアルバムが24時間で消えることでそのアルバムの写真の価値を高めることができる。

作った背景

旅行などの思い出の詰まった写真たちでも、いつでも見ることができる環境では見なおさない。

推し技術

Supabase, Next.js, tailwindcss, shadcn_ui

プロジェクト詳細

プロジェクト概要

「24時間で消えるアルバム」は、作ったアルバムが開封してから24時間後に閲覧できんくなるWebアプリケーションです。閲覧期限があることで思い出の詰まった写真たちの価値を高めることができます。

  • ユーザーフロー:
  1. 新規登録・ログイン: ユーザーはアカウントを作成し、ログインします。

  2. アルバム作成: ユーザーは任意の名前を付け、写真を複数枚アップロードしてアルバムを作成します。コメントも一緒につけることが可能です。 作成したアルバムは開封するまでであれば後からでも写真の追加をすることができます。

  3. 閲覧: 「開封」ボタンを押すと、その時点から24時間のカウントダウンが開始されます。「アルバムを開くこと」ボタンを押すとそのアルバムを閲覧できます。

  4. 消滅: 閲覧開始から24時間後、アルバムは自動的にロックされダッシュボードから表示されんくなり、誰からも見られなくなります。

技術スタック

  • フロントエンド: Next.js (App Router)

Reactのフレームワークであり、ルーティング、APIの管理、SSR/SSGによる高速なページ表示を実現します。

  • UIライブラリ: shadcn_ui

Tailwind CSSとRadix UIをベースにしたコンポーネント集です。高いカスタマイズ性と、クリーンなデザインを両立させ、迅速なUI開発を可能にしました。

  • バックエンド: Supabase

オープンソースのBaaS(Backend as a Service)であり、データベース(PostgreSQL)、認証機能、ファイルストレージ、API生成を統合的に提供します。

  • デプロイ: Vercel

Next.jsのアプリケーションに最適化されたホスティングプラットフォームです。Gitとの連携により、コードをプッシュするだけで自動的にデプロイが行われます。

構成図

image

詳細

ユーザー: ブラウザ(PC、スマートフォン)からアプリケーションにアクセスします。

Next.js(Vercel): フロントエンド: ユーザーインターフェースを提供します。

API Route: バックエンドとして機能し、Supabaseと通信してデータの読み書きを行います。

Supabase: ・Auth: ユーザーのログインと認証を管理します。

・Database (PostgreSQL): アルバム情報(閲覧日時、有効期限など)を管理します。

・Storage: アップロードされた写真ファイルを保存します。

参考動画

ホームページ

※スマートフォン、PC両対応のためのレスポンシブデザインにこだわりました。Tailwind CSSのブレークポイントを活用し、画面サイズに応じて最適なレイアウトに切り替わります。 <PC> image <スマートフォン> image

新規登録およびログイン

image

アルバム作成&期間限定閲覧

image

デモプレイに関する注記

ハッカソンの成果発表デモのため、このサイトでは特別に「24時間」の制限を「30秒」に変更しています。

▼ デモ用の時間制限ロジック(一部抜粋)

// アルバムのアクセス可能性をチェックする関数 export function checkAlbumAccess(album: Album) { // ... // 本来は24時間 (24 * 60 * 60 * 1000) const DURATION_MS = 30 * 1000; // デモ用に30秒に設定 const now = new Date(); const unlockDate = new Date(album.unlock_date); const unlockEnd = new Date(unlockDate.getTime() + DURATION_MS); if (now >= unlockDate && now < unlockEnd) { // アクセス可能 return { canAccess: true, status: 'unlocked', timeRemaining: unlockEnd.getTime() - now.getTime(), }; } else { // アクセス不可 // ... } }

Keishi Kanzaki

@42a3a80cdbbed32b