mirror of
https://github.com/dogkeeper886/ollama37.git
synced 2025-12-11 08:17:03 +00:00
web: newsletter signup on download page
This commit is contained in:
17
web/app/api/signup/route.ts
Normal file
17
web/app/api/signup/route.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Analytics } from '@segment/analytics-node'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
|
||||
const analytics = new Analytics({ writeKey: process.env.TELEMETRY_WRITE_KEY || '<empty>' })
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const { email } = await req.json()
|
||||
|
||||
analytics.identify({
|
||||
anonymousId: uuid(),
|
||||
traits: {
|
||||
email,
|
||||
},
|
||||
})
|
||||
|
||||
return new Response(null, { status: 200 })
|
||||
}
|
||||
11
web/app/download/downloader.tsx
Normal file
11
web/app/download/downloader.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
|
||||
export default function ({ url }: { url: string }) {
|
||||
useEffect(() => {
|
||||
window.location.href = url
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
import { redirect } from 'next/navigation'
|
||||
import Downloader from './downloader'
|
||||
import Signup from './signup'
|
||||
|
||||
export default async function Download() {
|
||||
const res = await fetch('https://api.github.com/repos/jmorganca/ollama/releases', { next: { revalidate: 60 } })
|
||||
const data = await res.json()
|
||||
|
||||
if (data.length === 0) {
|
||||
return new Response('not found', { status: 404 })
|
||||
return null
|
||||
}
|
||||
|
||||
const latest = data[0]
|
||||
const assets = latest.assets || []
|
||||
|
||||
if (assets.length === 0) {
|
||||
return new Response('not found', { status: 404 })
|
||||
return null
|
||||
}
|
||||
|
||||
// todo: get the correct asset for the current arch/os
|
||||
@@ -21,12 +22,26 @@ export default async function Download() {
|
||||
)
|
||||
|
||||
if (!asset) {
|
||||
return new Response('not found', { status: 404 })
|
||||
return null
|
||||
}
|
||||
|
||||
if (asset) {
|
||||
redirect(asset.browser_download_url)
|
||||
}
|
||||
|
||||
return null
|
||||
return (
|
||||
<main className='flex min-h-screen max-w-2xl flex-col p-4 lg:p-24 items-center mx-auto'>
|
||||
<img src='/ollama.png' className='w-16 h-auto' />
|
||||
<section className='my-12 text-center'>
|
||||
<h2 className='my-2 max-w-md text-3xl tracking-tight'>Downloading Ollama</h2>
|
||||
<h3 className='text-sm text-neutral-500'>
|
||||
Problems downloading?{' '}
|
||||
<a href={asset.browser_download_url} className='underline'>
|
||||
Try again
|
||||
</a>
|
||||
</h3>
|
||||
<Downloader url={asset.browser_download_url} />
|
||||
</section>
|
||||
<section className='max-w-sm flex flex-col w-full items-center border border-neutral-200 rounded-xl px-8 pt-8 pb-2'>
|
||||
<p className='text-lg leading-tight text-center mb-6 max-w-[260px]'>Sign up for updates</p>
|
||||
<Signup />
|
||||
</section>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
46
web/app/download/signup.tsx
Normal file
46
web/app/download/signup.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
|
||||
export default function () {
|
||||
const [email, setEmail] = useState('')
|
||||
const [success, setSuccess] = useState(false)
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={async e => {
|
||||
e.preventDefault()
|
||||
|
||||
await fetch('/api/signup', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ email }),
|
||||
})
|
||||
|
||||
setSuccess(true)
|
||||
setEmail('')
|
||||
|
||||
return false
|
||||
}}
|
||||
className='flex self-stretch flex-col gap-3 h-32'
|
||||
>
|
||||
<input
|
||||
required
|
||||
autoFocus
|
||||
value={email}
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
type='email'
|
||||
placeholder='your@email.com'
|
||||
className='bg-neutral-100 rounded-lg px-4 py-2 focus:outline-none placeholder-neutral-500'
|
||||
/>
|
||||
<input
|
||||
type='submit'
|
||||
value='Get updates'
|
||||
className='bg-black text-white rounded-lg px-4 py-2 focus:outline-none cursor-pointer'
|
||||
/>
|
||||
{success && <p className='text-center text-sm'>You're signed up for updates</p>}
|
||||
</form>
|
||||
)
|
||||
}
|
||||
@@ -8,7 +8,7 @@ export const metadata = {
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html lang='en'>
|
||||
<body>{children}</body>
|
||||
<body className='antialiased'>{children}</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import models from '../../models.json'
|
||||
export default async function Home() {
|
||||
return (
|
||||
<main className='flex min-h-screen max-w-2xl flex-col p-4 lg:p-24'>
|
||||
<img src='/ollama.png' className='w-20 h-auto' />
|
||||
<img src='/ollama.png' className='w-16 h-auto' />
|
||||
<section className='my-4'>
|
||||
<p className='my-3 max-w-md'>
|
||||
<a className='underline' href='https://github.com/jmorganca/ollama'>
|
||||
@@ -14,7 +14,7 @@ export default async function Home() {
|
||||
is a tool for running large language models, currently for macOS with Windows and Linux coming soon.
|
||||
<br />
|
||||
<br />
|
||||
<a href='/download' target='_blank'>
|
||||
<a href='/download'>
|
||||
<button className='bg-black text-white text-sm py-2 px-3 rounded-lg flex items-center gap-2'>
|
||||
<AiFillApple className='h-auto w-5 relative -top-px' /> Download for macOS
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user