trypear / pear-landing-page

Landing page for PearAI, the Open Source AI-Powered Code Editor
https://trypear.ai
35 stars 64 forks source link

[Medium][LandingPage+Server] Download App Feature #164

Closed Fryingpannn closed 1 month ago

Fryingpannn commented 1 month ago

Context

(Requires full stack) We need to be able to download the app directly from the landing page (https://trypear.ai/pricing). Currently the buttons are disabled and we can only allow people by sending them google drive link (LUL).

In this PR, we have the foundational code for the download endpoint on the server, and needs to be further worked upon. For app download, we should probably use object storage on Digital ocean, but for now directly within the server is fine too.

Solution

Flow should be (all authed): NextJS UI --> NextJS backend --> Python backend server.

Example code

NextJS UI:

import { useSupabaseClient } from '@supabase/auth-helpers-react'

function DownloadButton() {
  const supabase = useSupabaseClient()

  async function handleDownload() {
    const { data: { user } } = await supabase.auth.getUser()
    if (!user) {
      alert('Please log in to download')
      return
    }

    const response = await fetch('/api/download', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ userId: user.id }),
    })

    if (response.ok) {
      const { downloadUrl } = await response.json()
      window.location.href = downloadUrl
    } else {
      alert('Download failed. Please try again.')
    }
  }

  return <button onClick={handleDownload}>Download App</button>
}

NextJS backend

// pages/api/download.js
import { createClient } from '@supabase/supabase-js'

export default async function handler(req, res) {
  const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY)

  const { userId } = req.body

  // Check user's download permission in Supabase
  const { data, error } = await supabase
    .from('users')
    .select('can_download')
    .eq('id', userId)
    .single()

  if (error || !data.can_download) {
    return res.status(403).json({ error: 'No download permission' })
  }

  // Request download URL from Python backend
  const pythonBackendResponse = await fetch('https://your-digitalocean-server.com/generate-download-url', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ userId }),
  })

  if (!pythonBackendResponse.ok) {
    return res.status(500).json({ error: 'Failed to generate download URL' })
  }

  const { downloadUrl } = await pythonBackendResponse.json()
  res.status(200).json({ downloadUrl })
}

Python server https://github.com/trypear/pearai-server/pull/81

wflore19 commented 1 month ago

I can work on this šŸ™‹ā€ā™‚ļø

wflore19 commented 1 month ago

@Fryingpannn what are the expected parameters and response structure for the POST ${PEARAI_SERVER_URL}/generate-download-url endpoint?