Logo

dev-resources.site

for different kinds of informations.

Wedding Memories: The Collaborative Wedding Album!

Published at
10/11/2024
Categories
devchallenge
pinatachallenge
webdev
api
Author
femi_akinyemi
Author
13 person written this
femi_akinyemi
open
Wedding Memories: The Collaborative Wedding Album!

Wedding Memories

This is a submission for the The Pinata Challenge

What I Built

Wedding Memories is an app designed to capture, share, and cherish every unforgettable moment from your special day! It allows wedding guests to easily upload photos, creating a collaborative album that captures the essence of the celebration. By using Pinata's Files API, the app provides a seamless experience for secure and efficient media uploads and storage.

Demo

Check out the live version of the app here: Wedding Memories

Screenshots:

  • Upload Section - A user-friendly interface for selecting and uploading media files:

Image description

  • Gallery View - Displays all uploaded memories in a responsive layout:

Image description

Image description

  • Mobile-Optimized Design - Ensures smooth user experience across all devices:

Image description

  • Download Options - Guests can download their favourite moments to keep memories forever.

Image description

My Code

You can explore the full code for this project on GitHub:

View on GitHub

More Details

Wedding Memories leverages Pinataโ€™s Files API to build secure and efficient file uploads. Below is a brief breakdown of the integration:

  • File Uploads: Guests can easily upload images directly from their devices. This is accomplished using the pinata.upload.file, which uses JWT-based authentication to ensure secure file handling. Once uploaded, the files are securely stored, and their unique identifiers (CIDs) are generated for retrieval.

  • Local Previews Before Upload: To enhance the guest experience, wedding memories generate local previews of images before uploading them. This feature allows guests to confirm their selections and make adjustments, ensuring only their desired image is submitted.

After successful uploads, the files are rendered using the file API. This guarantees rapid access to the content, providing guests with a seamless experience when viewing shared memories.

  • Download Feature: Guests can now download their favourite photos directly from the app, making it easy to save cherished memories to their devices. The app includes an API route that facilitates the secure downloading of files.

API Integration Breakdown:

The building includes several key API routes, each designed to handle specific functionalities:

  • File Upload Endpoint

This accepts file uploads and stores them using Pinataโ€™s upload function. It then generates a signed URL for easy access to the uploaded file.

import { NextResponse, NextRequest } from "next/server";
import { pinata } from "../../../../utils/config";


export async function POST(request: NextRequest) {
  try {
    const data = await request.formData();
    const file: File | null = data.get("file") as unknown as File;
    const uploadData = await pinata.upload.file(file)
    const url = await pinata.gateways.createSignedURL({
        cid: uploadData.cid,
        expires: 3600,
    });
    return NextResponse.json(url, { status: 200 });
  } catch (e) {
    console.log(e);
    return NextResponse.json(
      { error: "Internal Server Error" },
      { status: 500 }
    );
  }
}

Enter fullscreen mode Exit fullscreen mode
  • API Key Generation (/api/key/route.ts):

Creates a temporary API key with permissions to pin files to IPFS.


/* eslint-disable @typescript-eslint/no-unused-vars */
import { NextResponse } from "next/server";
import { pinata } from "../../../../utils/config";

export const dynamic = "force-dynamic";

export async function GET() {
    try {
        const uuid = crypto.randomUUID();
        const keyData = await pinata.keys.create({
            keyName: uuid.toString(),
            permissions: {
                endpoints: {
                    pinning: {
                        pinFileToIPFS: true,
                    },
                },
            },
            maxUses: 1,
        })
        return NextResponse.json(keyData, { status: 200 });
    } catch (error) {
        console.log(error);
        return NextResponse.json({ text: "Error creating API Key:" }, { status: 500 });
    }
}

Enter fullscreen mode Exit fullscreen mode
  • List Files (/api/listfiles/route.ts):

Retrieves a list of uploaded files from Pinata, allowing users to view all shared content in the gallery

import { NextResponse } from "next/server";
import { env } from "process";


export const dynamic = "force-dynamic";

export async function GET() {
  try {
    const options: RequestInit = {
      method: 'GET',
      headers: {
          Authorization: `Bearer ${process.env.NEXT_PUBLIC_PINATA_JWT}`,
      },
      cache: 'no-cache'
    };

    const response = await fetch('https://api.pinata.cloud/v3/files', options);

    if (!response.ok) {
      return NextResponse.json({ text: "Error listing files" }, { status: response.status });
    }

    const { data } = await response.json();
    return NextResponse.json(data, { status: 200 });
  } catch (error) {
    console.log(error, "Error listing files");
    return NextResponse.json({ text: "Error listing files" }, { status: 500 });
  }
}

Enter fullscreen mode Exit fullscreen mode
  • Image Proxy (/api/proxy/route.ts):

Acts as a proxy for fetching images from external sources, ensuring users can easily access and download their images.

import { NextResponse } from 'next/server';


export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const imageUrl = searchParams.get('url'); // Get the image URL from the query string

  if (!imageUrl) {
    return NextResponse.json({ error: 'Image URL is required' }, { status: 400 });
  }

  try {
    const response = await fetch(imageUrl);

    if (!response.ok) {
      return NextResponse.json({ error: 'Failed to fetch image' }, { status: response.status });
    }

    const contentType = response.headers.get('content-type') || 'application/octet-stream';
    const imageBuffer = await response.arrayBuffer();

    return new NextResponse(imageBuffer, {
      headers: {
        'Content-Type': contentType,
        'Content-Disposition': 'attachment; filename="downloaded_image"',
      },
    });
  } catch (error) {
    console.error('Error fetching image:', error);
    return NextResponse.json({ error: 'Error fetching image' }, { status: 500 });
  }
}

Enter fullscreen mode Exit fullscreen mode
  • Signed URL Creation (/api/sign/route.ts):

Generates signed URLs for uploaded files.


import { type NextRequest, NextResponse } from "next/server";
import { pinata } from "../../../../utils/config";

export const dynamic = "force-dynamic";

export async function POST(req: NextRequest) {
  try {
    const data = await req.json();
    const mimeType = data.mime_type;

    let url;

    if (mimeType === 'video/mp4') {
      url = await pinata.gateways.createSignedURL({
        cid: data.cid,
        expires: 7776000,
      })
    } else {
      url = await pinata.gateways.createSignedURL({
        cid: data.cid,
        expires: 7776000,
      }).optimizeImage({
        width: 300,
        height: 300,
        format: "webp",
        fit: "contain",
        quality: 90,
        dpr: 2,
        sharpen: 1,

      });
    }

    return NextResponse.json(url, { status: 200 });
  } catch (error) {
    console.log(error);
    return NextResponse.json({ text: "Error creating signed URL:" }, { status: 500 });
  }
}

Enter fullscreen mode Exit fullscreen mode

The app is built with:

  • Pinata: File API

  • Frontend: React, Next.js, Framer Motion

  • Styling: Tailwind CSS for responsive, beautiful layouts.

  • Hosting: Amplify for deployment.

Conclusion

Weddings are joyous occasions filled with love, laughter, and countless memorable moments. Capturing these precious memories is essential, and with the Wedding Memories app, it's now easier than ever!

This application allows every guest to take lovely pictures on the event day and share them seamlessly, ensuring that no moment is missed and everyone has access to the collective memories of the celebration.

The app harnesses the power of Pinata's Files API to provide a secure and efficient way for guests to upload and share their photos and videos, creating a collaborative album that beautifully encapsulates the essence of the day.

For more details on how the app integrates with Pinata and to explore its capabilities, please refer to the Pinata documentation.

Thank you.


pinatachallenge Article's
30 articles in total
Favicon
French Paintings: The Intersection of Elegance, History, and Artistic Mastery at The Nicholson Gallery
Favicon
Revamped UI for NFT Artworks
Favicon
Chat with your PDF using Pinata,OpenAI and Streamlit
Favicon
The Pinata Challenge: Pinata File Hub - Seamless File Management & Uploads
Favicon
Wedding Memories: The Collaborative Wedding Album!
Favicon
Secure File Share - A safer way to share sensitive files online
Favicon
Pinata OG! | Generate beautiful OpenGraph Images with Pinata File API
Favicon
Congrats to The Pinata Challenge Winners!
Favicon
Noisy Monsters ๐ŸŽถ๐Ÿ‘พ
Favicon
Live_iy (Bring your static portraits to life)
Favicon
Image Optimizer Powered by Pinata: Secure File Storage Meets Real-Time Customization
Favicon
MINTIFY - EMPOWERING COMMUNITIES, CELEBERATING ACHIEVEMENTS!
Favicon
A decentralized file storage system using PINATA and IPFS
Favicon
ThrashBucket, store and share files anonymously
Favicon
Image Annotation for AI Model training using Pinata
Favicon
SnipShot: A Stylish Code Snippet Uploader Using Pinata IPFS
Favicon
๐ŸŽจ๐Ÿ–Œ๏ธDigital Collaborative Sketchbook: A Web App for Creating and Storing Art โœŽ
Favicon
CrewSpace: Collaborative File Sharing & Spaces for Friends
Favicon
Pinata Filesystem and PinDrop
Favicon
Mystical Palm Reader AI
Favicon
VidSnap: Effortless Screen Recording powered by Pinata
Favicon
Decentralized Firebase Remote Config
Favicon
Pixxsha - Share Your Moments Your Way
Favicon
3D Virtual Art Museum/Gallery
Favicon
Introducing PinDrop - Your visual discovery platform
Favicon
MySQL&PostgreSQL UI client for testing and querying databases with the query+result uploaded to Pinata
Favicon
StashIt: Your Game Assets Storage Hub | Powered by Pinata ๐Ÿช… IPFS SDK
Favicon
Haiku Harmony: Crafting Poetry in the Cloud with Pinata
Favicon
Web App to study effectively with flashcards, space repetition, images, and audios
Favicon
PikPok โ€“ Share Your Creativity, Your Way.

Featured ones: