Merge pull request #326 from supabase/feat/new_website

Feat/new website
This commit is contained in:
Copple authored and GitHub committed 2020-12-03 17:33:30 +08:00
commit 027696d60d
19 files changed
+870 -449

No files matched your search

+2 -8
View File
@@ -32,14 +32,8 @@ const Button = (props: Props) => {
className={`
relative transition-all ${url ? textClass : ''}
`}
>
{text}
</span>
{url && (
<span className={`ml-2 transition-all opacity-0 group-hover:opacity-100 ${arrowClass}`}>
→
</span>
)}
>{text}</span>
{url && (<span className={`ml-2 transition-all opacity-0 group-hover:opacity-100 ${arrowClass}`}>→</span>)}
</button>
)
+91 -81
View File
@@ -61,101 +61,111 @@ const Footer = (props: Props) => {
Footer
</h2>
<div className="container mx-auto px-8 sm:px-16 xl:px-20 py-12 lg:pt-16 lg:pb-32">
<div className="mx-auto max-w-7xl">
<div className="xl:grid xl:grid-cols-3 xl:gap-8">
<div className="space-y-8 xl:col-span-1">
<img
className="h-10 w-auto"
src={darkMode ? `${basePath}/images/logo-dark.png` : `${basePath}/images/logo-light.png`}
alt="Supabase"
/>
<div className="flex space-x-6">
<a
href="https://twitter.com/supabase_io"
className="text-gray-300 hover:text-gray-400"
>
<span className="sr-only">Twitter</span>
<svg className="h-6 w-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0022 5.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.072 4.072 0 012.8 9.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 012 18.407a11.616 11.616 0 006.29 1.84" />
</svg>
</a>
<div className="mx-auto max-w-7xl">
<div className="xl:grid xl:grid-cols-3 xl:gap-8">
<div className="space-y-8 xl:col-span-1">
<img
className="h-10 w-auto"
src={darkMode ? 'images/logo-dark.png' : 'images/logo-light.png'}
alt="Supabase"
/>
<div className="flex space-x-6">
<a
href="https://twitter.com/supabase_io"
className="text-gray-300 hover:text-gray-400"
>
<span className="sr-only">Twitter</span>
<svg
className="h-6 w-6"
fill="currentColor"
viewBox="0 0 24 24"
aria-hidden="true"
>
<path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0022 5.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.072 4.072 0 012.8 9.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 012 18.407a11.616 11.616 0 006.29 1.84" />
</svg>
</a>
<a href="https://github.com/supabase" className="text-gray-300 hover:text-gray-400">
<span className="sr-only">GitHub</span>
<svg className="h-6 w-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path
fillRule="evenodd"
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
clipRule="evenodd"
/>
</svg>
</a>
<a href="https://github.com/supabase" className="text-gray-300 hover:text-gray-400">
<span className="sr-only">GitHub</span>
<svg
className="h-6 w-6"
fill="currentColor"
viewBox="0 0 24 24"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
clipRule="evenodd"
/>
</svg>
</a>
</div>
</div>
<div className="mt-12 grid grid-cols-1 gap-8 xl:mt-0 xl:col-span-2">
<div className="grid grid-cols-2 gap-8 md:grid-cols-4">
{FooterLinks.map((segment: any) => {
return (
<div key={`footer_${segment.title}`}>
<h3 className="text-sm font-semibold text-gray-400 dark:text-dark-400 tracking-wider uppercase">
{segment.title}
</h3>
<ul className="mt-4 space-y-4">
{segment.links.map((link: any, idx: number) => (
<li key={`${segment.title}_link_${idx}`}>
<a
href={link.url}
className={`text-base ${
link.url
? 'text-gray-500 dark:text-dark-100'
: 'text-gray-400 dark:text-dark-200'
} hover:text-gray-900 dark:hover:text-gray-300`}
>
{link.text}
{!link.url && (
<span className="block text-sm text-gray-300 dark:text-dark-300">
Coming soon
</span>
)}
</a>
</li>
))}
</ul>
</div>
)
})}
</div>
</div>
</div>
<div className="mt-12 grid grid-cols-1 gap-8 xl:mt-0 xl:col-span-2">
<div className="grid grid-cols-2 gap-8 md:grid-cols-4">
{FooterLinks.map((segment: any) => {
return (
<div key={`footer_${segment.title}`}>
<h3 className="text-sm font-semibold text-gray-400 dark:text-dark-400 tracking-wider uppercase">
{segment.title}
</h3>
<ul className="mt-4 space-y-4">
{segment.links.map((link: any, idx: number) => (
<li key={`${segment.title}_link_${idx}`}>
<a
href={link.url}
className={`text-base ${
link.url
? 'text-gray-500 dark:text-dark-100'
: 'text-gray-400 dark:text-dark-200'
} hover:text-gray-900 dark:hover:text-gray-300`}
>
{link.text}
{!link.url && (
<span className="block text-sm text-gray-300 dark:text-dark-300">
Coming soon
</span>
)}
</a>
</li>
))}
</ul>
</div>
)
})}
</div>
</div>
</div>
<div className="mt-12 border-t border-gray-200 dark:border-dark-600 pt-8 flex justify-between">
<p className="text-base text-gray-400 dark:text-dark-400">&copy; Supabase Inc</p>
<div className="flex items-center">
<SunEmoji />
<button
type="button"
aria-pressed="false"
className={`
<div className="mt-12 border-t border-gray-200 dark:border-dark-600 pt-8 flex justify-between">
<p className="text-base text-gray-400 dark:text-dark-400">&copy; Supabase Inc</p>
<div className="flex items-center">
<SunEmoji />
<button
type="button"
aria-pressed="false"
className={`
relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer
transition-colors ease-in-out duration-200 focus:outline-none ${
darkMode ? 'bg-dark-500' : 'bg-gray-200'
} mx-5
`}
onClick={() => toggleDarkMode()}
>
<span className="sr-only">Toggle Themes</span>
<span
aria-hidden="true"
className={`
onClick={() => toggleDarkMode()}
>
<span className="sr-only">Toggle Themes</span>
<span
aria-hidden="true"
className={`
${darkMode ? 'translate-x-5' : 'translate-x-0'} inline-block h-5 w-5 rounded-full
bg-white dark:bg-dark-700 shadow-lg transform ring-0 transition ease-in-out duration-200
`}
/>
</button>
<MoonEmoji />
/>
</button>
<MoonEmoji />
</div>
</div>
</div>
</div>
</div>
</footer>
)
}
+4 -6
View File
@@ -67,11 +67,6 @@ const Hero = () => {
src={`${basePath}/images/logos/mozilla--grey.png`}
alt="Mozilla"
/>
<img
className="h-3 sm:h-5 pr-10"
src={`${basePath}/images/logos/coatue.png`}
alt="Coatue"
/>
</div>
</div>
</div>
@@ -83,7 +78,10 @@ const Hero = () => {
<div className="h-2 w-2 mr-2 rounded-full bg-dark-500" />
<div className="h-2 w-2 mr-2 rounded-full bg-dark-500" />
</div>
<div className="w-full relative bg-dark-900 pointer-events-none" style={{ padding: '56.25% 0 0 0' }}>
<div
className="w-full relative bg-dark-900 pointer-events-none"
style={{ padding: '56.25% 0 0 0' }}
>
<iframe
className="absolute w-full h-full rounded-b-md"
src="https://www.youtube.com/embed/dBOSUER_5T4?playlist=dBOSUER_5T4&autoplay=1&loop=1&controls=0&modestbranding=1&rel=0&disablekb=1&mute=1&muted=1"
+2 -2
View File
@@ -36,10 +36,10 @@ const MadeForDevelopers = () => {
return (
<div className={blockClass} key={`dev_feature_${idx}`}>
<div className="lg:mt-5">
<dt className="text-lg leading-6 font-medium text-gray-900 dark:text-white flex md:flex-col xl:flex-row">
<dt className="text-lg leading-6 font-medium text-gray-900 dark:text-white flex flex-row sm:flex-col xl:flex-row">
{feature.name}
{feature.badge && (
<Badge className="ml-3 md:ml-0 md:w-20 md:mt-2 xl:ml-3 xl:mt-0 xl:w-auto">
<Badge className="ml-3 sm:ml-0 sm:w-20 sm:mt-2 xl:ml-3 xl:mt-0 xl:w-auto">
{feature.badge}
</Badge>
)}
+100
View File
@@ -0,0 +1,100 @@
import React from 'react'
import CompanyData from 'data/Company.json'
import BlogPostsData from 'data/BlogPosts.json'
type Props = {
text: string
description? : string
url? : string
icon? : string
}
const Company = () => {
const iconSections = Object.values(CompanyData).map((company : Props) => {
const { text, description, url, icon } = company
const content = (
<a
href="#"
className="-m-3 p-3 flex items-start rounded-lg hover:bg-gray-50 dark:hover:bg-dark-700 transition ease-in-out duration-150"
>
{/* <!-- Heroicon name: support --> */}
<svg
className="flex-shrink-0 h-6 w-6 stroke-gray dark:stroke-white "
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d={icon}
/>
</svg>
<div className="ml-4">
<p className="text-base font-medium text-gray-900 dark:text-white">{text}</p>
<p className="mt-1 text-sm text-gray-500 dark:text-dark-300">{description}</p>
</div>
</a>
)
return (
<a
key={text}
href={url}
className="-m-3 p-3 flex flex-col justify-between rounded-lg transition ease-in-out duration-150"
>
{content}
</a>
)
})
return (
<React.Fragment>
<nav
className="grid gap-y-10 px-4 py-8 sm:grid-cols-2 sm:gap-x-8 sm:py-12 sm:px-6 lg:px-8 xl:pr-12"
aria-labelledby="solutionsHeading"
>
{iconSections}
</nav>
<div className="px-4 py-8 sm:py-12 sm:px-6 lg:px-8 xl:pl-12">
<div>
<h3 className="text-sm font-medium tracking-wide text-gray-500 dark:text-dark-300 uppercase">
Latest blog posts
</h3>
<ul className="mt-6 space-y-6">
{BlogPostsData.map((caseStudy: any, idx: number) => (
<li className="flow-root" key={`flyout_case_${idx}`}>
<a
href={caseStudy.url}
className="-m-3 py-3 flex rounded-lg hover:bg-gray-100 dark:hover:bg-dark-600 transition ease-in-out duration-150"
>
<div className="min-w-0 flex-1 sm:ml-3">
<h4 className="text-base font-medium text-gray-900 dark:text-white truncate">
{caseStudy.title}
</h4>
<p className="mt-1 text-sm text-gray-500 dark:text-dark-300">
{caseStudy.description}
</p>
</div>
</a>
</li>
))}
</ul>
</div>
<div className="mt-6 text-sm font-medium">
<a
href="https://supabase.io/blog"
className="text-gray-600 hover:text-gray-500 dark:text-brand-600 dark:hover:text-brand-700 transition ease-in-out duration-150"
>
View all posts <span aria-hidden="true">&rarr;</span>
</a>
</div>
</div>
</React.Fragment>
)
}
export default Company
+107
View File
@@ -0,0 +1,107 @@
import React from 'react'
import DevelopersData from 'data/Developers.json'
import AnnouncementsData from 'data/Announcements.json'
type Props = {
text: string
description? : string
url? : string
icon? : string
}
const Developers = () => {
const iconSections = Object.values(DevelopersData).map((company : Props) => {
const { text, description, url, icon } = company
const content = (
<a
href="#"
className="-m-3 p-3 flex items-start rounded-lg hover:bg-gray-50 dark:hover:bg-dark-700 transition ease-in-out duration-150"
>
{/* <!-- Heroicon name: support --> */}
<svg
className="flex-shrink-0 h-6 w-6 stroke-gray dark:stroke-white "
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d={icon}
/>
</svg>
<div className="ml-4">
<p className="text-base font-medium text-gray-900 dark:text-white">{text}</p>
<p className="mt-1 text-sm text-gray-500 dark:text-dark-300">{description}</p>
</div>
</a>
)
return url ? (
<a
key={text}
href="#"
className="-m-3 p-3 flex flex-col justify-between rounded-lg transition ease-in-out duration-150"
>
{content}
</a>
) : (
<div
key={text}
className="-m-3 p-3 flex flex-col justify-between rounded-lg transition ease-in-out duration-150"
>
{content}
</div>
)
})
return (
<React.Fragment>
<nav
className="grid gap-y-10 px-4 py-8 sm:grid-cols-2 sm:gap-x-8 sm:py-12 sm:px-6 lg:px-8 xl:pr-12"
aria-labelledby="solutionsHeading"
>
{iconSections}
</nav>
<div className="px-4 py-8 sm:py-12 sm:px-6 lg:px-8 xl:pl-12">
<div>
<h3 className="text-sm font-medium tracking-wide text-gray-500 dark:text-dark-300 uppercase">
Latest announcements
</h3>
<ul className="mt-6 space-y-16">
{AnnouncementsData.map((caseStudy: any, idx: number) => (
<li className="flow-root" key={`flyout_case_${idx}`}>
<a
href={caseStudy.url}
className="-m-3 p-3 flex rounded-lg hover:bg-gray-100 dark:hover:bg-dark-600 transition ease-in-out duration-150"
>
<div className="hidden sm:block flex-shrink-0">
<img
className="w-32 h-20 object-cover rounded-md"
src={caseStudy.imgUrl}
alt="caseStudyThumb"
/>
</div>
<div className="min-w-0 flex-1 sm:ml-8">
<h4 className="text-base font-medium text-gray-900 dark:text-white truncate">
{caseStudy.title}
</h4>
<p className="mt-1 text-sm text-gray-500 dark:text-dark-300">
{caseStudy.description}
</p>
</div>
</a>
</li>
))}
</ul>
</div>
</div>
</React.Fragment>
)
}
export default Developers
-194
View File
@@ -1,194 +0,0 @@
import { useState, useEffect } from 'react'
import Badge from 'components/Badge'
import Transition from 'lib/Transition'
import Solutions from 'data/Solutions.json'
import CaseStudiesData from 'data/CaseStudies.json'
import { useRouter } from 'next/router'
const FlyOut = () => {
const { basePath } = useRouter()
const [show, setShow] = useState(false)
function handleToggle() {
setShow(!show)
}
useEffect(() => {
// window is accessible here.
window.addEventListener('scroll', function (e) {
// close Fly Out window if user scrolls past 96px from top
if (window.pageYOffset > 96) {
setShow(false)
}
})
}, [])
const iconSections = Object.values(Solutions).map((solution) => {
const { name, description, icon, label, url } = solution
const content = (
<div className="flex md:h-full lg:flex-col">
<div className="flex-shrink-0">
<div className="inline-flex items-center justify-center h-10 w-10 rounded-md bg-gray-900 dark:bg-white text-white sm:h-12 sm:w-12">
<svg
className="h-6 w-6 stroke-white dark:stroke-black"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
aria-hidden="true"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d={icon} />
</svg>
</div>
</div>
<div className="ml-4 md:flex-1 md:flex md:flex-col md:justify-between lg:ml-0 lg:mt-4">
<div>
<p className="text-base font-medium text-gray-900 dark:text-white">
{name} {label && <Badge className="ml-3">{label}</Badge>}
</p>
<p className="mt-1 text-sm text-gray-500 dark:text-dark-300">{description}</p>
</div>
{url && (
<p className="mt-2 text-sm font-medium text-brand-600 lg:mt-4">
Learn more <span aria-hidden="true">&rarr;</span>
</p>
)}
</div>
</div>
)
return url ? (
<a
key={name}
href="#"
className="-m-3 p-3 flex flex-col justify-between rounded-lg hover:bg-gray-50 dark:hover:bg-dark-700 transition ease-in-out duration-150"
>
{content}
</a>
) : (
<div
key={name}
className="-m-3 p-3 flex flex-col justify-between rounded-lg transition ease-in-out duration-150"
>
{content}
</div>
)
})
return (
<>
<a
href="#"
className="inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-dark-100 dark:hover:border-dark-100"
onClick={() => handleToggle()}
>
<span>Product</span>
<svg
className="ml-2 h-5 w-5 text-gray-300 group-hover:text-gray-300 transition ease-in-out duration-150"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</a>
<Transition
appear={true}
show={show}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<>
<div
className="absolute inset-x-0 transform shadow-lg border-t border-gray-50 dark:border-dark-500"
style={{
zIndex: 999,
position: 'absolute',
width: '100vw',
margin: '0 auto',
marginTop: '64px',
left: '-50vw',
right: '-50vw',
}}
>
<div className="absolute inset-0 flex sm:flex-col lg:flex-row" aria-hidden="true">
<div className="bg-white dark:bg-dark-600 sm:w-full sm:h-1/2 lg:w-1/2 lg:h-full"></div>
<div className="bg-gray-50 dark:bg-dark-500 sm:w-full sm:h-1/2 lg:w-1/2 lg:h-full"></div>
{/* <div className="bg-gray-50 dark:bg-dark-300 md:hidden lg:block lg:w-1/2"></div> */}
</div>
<div className="relative max-w-7xl mx-auto grid grid-cols-1 lg:grid-cols-2">
<nav
className="grid gap-y-10 px-4 py-8 sm:grid-cols-2 sm:gap-x-8 sm:py-12 sm:px-6 lg:px-8 xl:pr-12"
aria-labelledby="solutionsHeading"
>
{iconSections}
</nav>
<div className="px-4 py-8 sm:py-12 sm:px-6 lg:px-8 xl:pl-12">
<div>
<h3 className="text-sm font-medium tracking-wide text-gray-500 dark:text-dark-300 uppercase">
Latest news
</h3>
<ul className="mt-6 space-y-6">
{CaseStudiesData.map((caseStudy: any, idx: number) => (
<li className="flow-root" key={`flyout_case_${idx}`}>
<a
href={caseStudy.url}
className="-m-3 p-3 flex rounded-lg hover:bg-gray-100 dark:hover:bg-dark-600 transition ease-in-out duration-150"
>
<div className="hidden sm:block flex-shrink-0">
<img
className="w-32 h-20 object-cover rounded-md"
src={`${basePath}/${caseStudy.imgUrl}`}
alt="caseStudyThumb"
/>
</div>
<div className="min-w-0 flex-1 sm:ml-8">
<h4 className="text-base font-medium text-gray-900 dark:text-white truncate">
{caseStudy.title}
</h4>
<p className="mt-1 text-sm text-gray-500 dark:text-dark-300">
{caseStudy.description}
</p>
</div>
</a>
</li>
))}
</ul>
</div>
<div className="mt-6 text-sm font-medium">
<a
href="/blog"
className="text-gray-600 hover:text-gray-500 dark:text-brand-600 dark:hover:text-brand-700 transition ease-in-out duration-150"
>
View all posts <span aria-hidden="true">&rarr;</span>
</a>
</div>
</div>
</div>
</div>
<div
className="fixed inset-0 transition-opacity"
style={{
zIndex: 100,
marginLeft: 0,
pointerEvents: 'visiblePainted',
}}
onClick={() => handleToggle()}
>
<div className="absolute inset-0 opacity-0"></div>
</div>
</>
</Transition>
</>
)
}
export default FlyOut
+111
View File
@@ -0,0 +1,111 @@
import React from 'react'
import Badge from 'components/Badge'
import SolutionsData from 'data/Solutions.json'
import CaseStudiesData from 'data/CaseStudies.json'
const Product = () => {
const iconSections = Object.values(SolutionsData).map((solution) => {
const { name, description, icon, label, url } = solution
const content = (
<div className="flex md:h-full lg:flex-col">
<div className="flex-shrink-0">
<div className="inline-flex items-center justify-center h-10 w-10 rounded-md bg-gray-900 dark:bg-white text-white sm:h-12 sm:w-12">
<svg
className="h-6 w-6 stroke-white dark:stroke-black"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
aria-hidden="true"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d={icon} />
</svg>
</div>
</div>
<div className="ml-4 md:flex-1 md:flex md:flex-col md:justify-between lg:ml-0 lg:mt-4">
<div>
<p className="text-base font-medium text-gray-900 dark:text-white">
{name} {label && <Badge className="ml-3">{label}</Badge>}
</p>
<p className="mt-1 text-sm text-gray-500 dark:text-dark-300">{description}</p>
</div>
{url && (
<p className="mt-2 text-sm font-medium text-brand-600 lg:mt-4">
Learn more <span aria-hidden="true">&rarr;</span>
</p>
)}
</div>
</div>
)
return url ? (
<a
key={name}
href="#"
className="-m-3 p-3 flex flex-col justify-between rounded-lg hover:bg-gray-50 dark:hover:bg-dark-700 transition ease-in-out duration-150"
>
{content}
</a>
) : (
<div
key={name}
className="-m-3 p-3 flex flex-col justify-between rounded-lg transition ease-in-out duration-150"
>
{content}
</div>
)
})
return (
<React.Fragment>
<nav
className="grid gap-y-10 px-4 py-8 sm:grid-cols-2 sm:gap-x-8 sm:py-12 sm:px-6 lg:px-8 xl:pr-12"
aria-labelledby="solutionsHeading"
>
{iconSections}
</nav>
<div className="px-4 py-8 sm:py-12 sm:px-6 lg:px-8 xl:pl-12">
<div>
<h3 className="text-sm font-medium tracking-wide text-gray-500 dark:text-dark-300 uppercase">
Latest case studies
</h3>
<ul className="mt-6 space-y-6">
{CaseStudiesData.map((caseStudy: any, idx: number) => (
<li className="flow-root" key={`flyout_case_${idx}`}>
<a
href={caseStudy.url}
className="-m-3 p-3 flex rounded-lg hover:bg-gray-100 dark:hover:bg-dark-600 transition ease-in-out duration-150"
>
<div className="hidden sm:block flex-shrink-0">
<img
className="w-32 h-20 object-cover rounded-md"
src={caseStudy.imgUrl}
alt="caseStudyThumb"
/>
</div>
<div className="min-w-0 flex-1 sm:ml-8">
<h4 className="text-base font-medium text-gray-900 dark:text-white truncate">
{caseStudy.title}
</h4>
<p className="mt-1 text-sm text-gray-500 dark:text-dark-300">
{caseStudy.description}
</p>
</div>
</a>
</li>
))}
</ul>
</div>
{/* <div className="mt-6 text-sm font-medium">
<a
href="/blog"
className="text-gray-600 hover:text-gray-500 dark:text-brand-600 dark:hover:text-brand-700 transition ease-in-out duration-150"
>
View all posts <span aria-hidden="true">&rarr;</span>
</a>
</div> */}
</div>
</React.Fragment>
)
}
export default Product
+81 -20
View File
@@ -3,9 +3,13 @@ import Link from 'next/link'
import { useRouter } from 'next/router'
import Badge from 'components/Badge'
import FlyOut from 'components/Nav/FlyOut'
import FlyOut from '~/components/UI/FlyOut'
import Transition from 'lib/Transition'
import Solutions from 'data/Solutions.json'
import SolutionsData from 'data/Solutions.json'
import Solutions from '~/components/Nav/Product'
import Developers from './Developers'
import Company from './Company'
type Props = {
darkMode: boolean
@@ -16,6 +20,10 @@ const Nav = (props: Props) => {
const { darkMode } = props
const [open, setOpen] = useState(false)
const [openProduct, setOpenProduct] = useState(false)
const [openDevelopers, setOpenDevelopers] = useState(false)
const [openCompany, setOpenCompany] = useState(false)
React.useEffect(() => {
if (open) {
console.log('open if')
@@ -26,7 +34,18 @@ const Nav = (props: Props) => {
}
}, [open])
const iconSections = Object.values(Solutions).map((solution: any, idx: number) => {
function handleToggle(callback: any) {
handleCancel()
callback()
}
function handleCancel() {
setOpenProduct(false)
setOpenDevelopers(false)
setOpenCompany(false)
}
const iconSections = Object.values(SolutionsData).map((solution: any, idx: number) => {
const { name, description, icon, label, url } = solution
const content = (
@@ -129,6 +148,36 @@ const Nav = (props: Props) => {
</div>
)
const FlyOutNavButton = (props: any) => (
<div
className={`
inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium text-gray-500 hover:text-gray-700
dark:text-dark-100 cursor-pointer
` + (props.active )}
onClick={props.onClick}
>
<>
<span>{props.title}</span>
<svg
className={
'ml-2 h-5 w-5 text-gray-300 group-hover:text-gray-300 transition ease-in-out duration-150' +
(props.active && ' transform rotate-180')
}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</>
</div>
)
return (
<nav className="bg-white dark:bg-dark-700 z-50 sticky">
<div className="lg:container mx-auto relative flex justify-between h-16 lg:px-10 xl:px-0">
@@ -149,26 +198,40 @@ const Nav = (props: Props) => {
/>
</div>
<div className="pl-4 hidden sm:ml-6 lg:flex sm:space-x-8">
<FlyOut />
<FlyOutNavButton
title={'Product'}
onClick={() => handleToggle(() => setOpenProduct(!openProduct))}
active={openProduct}
/>
<FlyOutNavButton
title={'Developers'}
onClick={() => handleToggle(() => setOpenDevelopers(!openDevelopers))}
active={openDevelopers}
/>
{/* <FlyOutNavButton
title={'Company'}
onClick={() => handleToggle(() => setOpenCompany(!openCompany))}
active={openCompany}
/> */}
<FlyOut open={openProduct} handleCancel={handleCancel}>
<Solutions />
</FlyOut>
<FlyOut open={openDevelopers} handleCancel={handleCancel}>
<Developers />
</FlyOut>
{/* <FlyOut open={openCompany} handleCancel={handleCancel}>
<Company />
</FlyOut> */}
<a
href="/docs"
href="/beta"
className={`
inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium
text-gray-500 hover:text-gray-700 hover:border-gray-500 p-5
dark:text-dark-100 dark:hover:border-dark-100
`}
>
Developers
</a>
<a
href="/docs/guides/platform"
className={`
inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium
text-gray-500 hover:text-gray-700 hover:border-gray-500 p-5
dark:text-dark-100 dark:hover:border-dark-100
`}
>
Company
Beta
</a>
<a
href="/docs/pricing"
@@ -187,11 +250,9 @@ const Nav = (props: Props) => {
href="https://app.supabase.io?auth=signup"
className={`
inline-flex items-center border-b-2 border-transparent text-sm font-normal transition
rounded-md px-3 py-1 mr-5 bg-brand-600 text-white hover:bg-brand-700 hidden lg:block
rounded-md px-3 py-1 mr-5 bg-brand-700 text-white hover:bg-brand-800 hidden lg:block
`}
>
Start your project
</a>
>Start your project</a>
<a
href="https://app.supabase.io?auth=signin"
className={`
+105
View File
@@ -0,0 +1,105 @@
import React, { useState, useEffect, useImperativeHandle, forwardRef } from 'react'
import Transition from 'lib/Transition'
type Props = {
title?: string
children?: React.ReactNode
className?: string
open?: boolean
handleCancel?: any
singleBgColor?: boolean
}
const FlyOut = (props: Props) => {
const { title = '', children, className = '', singleBgColor = false, handleCancel } = props
const [show, setShow] = useState(false)
useEffect(() => {
function handleScroll() {
if (window.pageYOffset > 96) handleCancel()
}
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
})
// function handleToggle() {
// setShow(!show)
// props.handleClick()
// }
// useImperativeHandle(
// ref,
// () => ({
// close() {
// setShow(false)
// }
// }),
// )
// useEffect(() => {
// // window is accessible here.
// window.addEventListener('scroll', function (e) {
// // close Fly Out window if user scrolls past 96px from top
// if (window.pageYOffset > 96) {
// setShow(false)
// }
// })
// }, [])
return (
<>
<Transition
appear={true}
show={props.open}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<>
<div
className="absolute inset-x-0 transform shadow-lg border-t border-gray-100 dark:border-dark-500"
style={{
zIndex: 999,
position: 'absolute',
width: '100vw',
margin: '0 auto',
marginTop: '63px',
left: '-50vw',
right: '-50vw',
top: 0,
}}
>
<div className="absolute inset-0 flex sm:flex-col lg:flex-row" aria-hidden="true">
<div className="bg-white dark:bg-dark-600 sm:w-full sm:h-1/2 lg:w-1/2 lg:h-full" />
<div className={`${singleBgColor ? 'bg-white dark:bg-dark-600' : 'bg-gray-50 dark:bg-dark-500'} sm:w-full sm:h-1/2 lg:w-1/2 lg:h-full`} />
{/* <div className="bg-gray-50 dark:bg-dark-300 md:hidden lg:block lg:w-1/2"></div> */}
</div>
<div
className={`relative max-w-7xl mx-auto grid grid-cols-1 lg:grid-cols-2 ${className}`}
>
{children}
</div>
</div>
<div
className="fixed inset-0 t-63 transition-opacity bg-red"
style={{
zIndex: 10,
top: '63px',
marginLeft: 0,
pointerEvents: 'visiblePainted',
}}
onClick={() => props.handleCancel()}
>
<div className="absolute inset-0 opacity-0"></div>
</div>
</>
</Transition>
</>
)
}
export default FlyOut
+18
View File
@@ -0,0 +1,18 @@
[
{
"type": "Announcement",
"title": "Beta launch",
"description": "We're excitied to announce we have moved from Alpha to Beta",
"imgUrl": "images/case-study-monitoro.jpg",
"logoUrl": "images/logos/monitoro.png",
"organization": "Monitoro",
"url": "/casestudies/monitoro",
"postMeta": {
"name" : "Paul Copplestone",
"avatarUrl": "https://avatars0.githubusercontent.com/u/10214025?v=4",
"publishDate": "Mar 16, 2020",
"readLength": 6
},
"ctaText": "View case study"
}
]
+14 -7
View File
@@ -163,15 +163,22 @@ export const IntroductionSegments = [
},
]
// Currently unused
export const PerformanceComparisonData = [
{
name: 'Supabase',
read: 1167,
write: 870
key: 'read',
title: 'Read (requests/s)',
stats: [
{ name: 'Supabase', value: 1167, color: 'bg-brand-600 dark:bg-brand-700' },
{ name: 'Firestore', value: 366, color: 'bg-dark-300 dark:bg-dark-400' },
]
},
{
name: 'Firestore',
read: 366,
write: 280
key: 'write',
title: 'Write (requests/s)',
stats: [
{ name: 'Supabase', value: 870, color: 'bg-brand-600 dark:bg-brand-700' },
{ name: 'Firestore', value: 280, color: 'bg-dark-300 dark:bg-dark-400' },
]
}
]
]
+26
View File
@@ -0,0 +1,26 @@
[
{
"type": "Blog post",
"title": "Tayfa Built a No-Code Website Builder Deployed in Seven Days",
"description": "",
"postMeta": {
"name" : "Paul Copplestone",
"avatarUrl": "https://supabase.io/blog/2020/12/02/case-study-xendit",
"publishDate": "",
"readLength": 6
},
"ctaText": "View blog post"
},
{
"type": "Blog post",
"title": "Supabase Partners With Strive School To Help Teach Open Source",
"description": "",
"postMeta": {
"name" : "Paul Copplestone",
"avatarUrl": "https://supabase.io/blog/2020/12/02/supabase-striveschool",
"publishDate": "",
"readLength": 6
},
"ctaText": "View blog post"
}
]
+26
View File
@@ -0,0 +1,26 @@
[
{
"text": "Blog",
"description": "Read the latest developments from Supabase",
"url": "https://supabase.io/blog",
"icon": "M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"
},
{
"text": "Open Source",
"description": "Supabase is an opensource company, supporting existing open source tools and communities wherever possible.",
"url": "https://supabase.io/oss",
"icon": "M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"
},
{
"text": "Humans.txt",
"description": "Overview of Supabase staff",
"url": "https://supabase.io/humans.txt",
"icon": "M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
},
{
"text": "Lawyers.txt",
"description": "Details of technology used by Supabase",
"url": "https://supabase.io/lawyers.txt",
"icon": "M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
}
]
+14
View File
@@ -0,0 +1,14 @@
[
{
"text": "Documentation",
"description": "Everything you need that makes it simple to get started.",
"url": "https://supabase.io/docs",
"icon": "M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
},
{
"text": "API reference",
"description": "Examples and references for using API libraries",
"url": "https://supabase.io/docs/client/supabase-client",
"icon": "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
}
]
+169 -131
View File
@@ -1,35 +1,82 @@
import Head from 'next/head'
import { useRef } from 'react'
import { useRef, useState } from 'react'
import Container from 'components/Container'
import Layout from 'components/Layout'
import CountUp from 'components/CountUp'
import FlyOut from 'components/UI/FlyOut'
import { APP_NAME, DESCRIPTION } from 'lib/constants'
import { AlphaNumbers, IntroductionSegments } from 'data/BetaPage'
import { useRouter } from 'next/router'
import { AlphaNumbers, IntroductionSegments, PerformanceComparisonData } from 'data/BetaPage'
import { render } from 'react-dom'
const site_title = `${APP_NAME} | We are now in Beta`
// Dark text: text-dark-400
// Light text: text-dark-300
const HamburgerMenu = () => (
<div className="cursor-pointer">
<svg
viewBox="0 0 24 24"
width="24"
height="24"
stroke="white"
strokeWidth="2"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<line x1="3" y1="12" x2="21" y2="12" />
<line x1="3" y1="6" x2="21" y2="6" />
<line x1="3" y1="18" x2="21" y2="18" />
</svg>
</div>
)
const NavFlyOutMenu = (props: any) => {
const { scrollTo } = props
const segments = IntroductionSegments.map((segment: any) => segment.chapters)
return (
<>
<div className="col-span-12 grid grid-cols-12 items-center border-dark-300 dark:border-dark-400 sm:border-r border-b border-dashed">
{segments.flat().map((segment: any) => (
<div
onClick={() => scrollTo(segment.key)}
className={`
col-span-12 lg:col-span-4 px-4 lg:px-6 py-4 lg:py-10 text-dark-300 dark:text-dark-400 cursor-pointer bg-white dark:bg-dark-600
hover:bg-dark-100 dark:hover:bg-dark-500 border-dark-300 dark:border-dark-400 border-t sm:border-l border-dashed`}
>
<p className="flex items-center text-black dark:text-white">
<span className="font-mono text-xs text-dark-300 dark:text-dark-400 mr-2">
0{segment.no}
</span>
<span>{segment.name}</span>
</p>
</div>
))}
</div>
</>
)
}
const VideoShot = (props: any) => {
const { src } = props
return (
<div className="shadow-lg rounded-md" style={{ height: 'fit-content' }}>
<div className="w-full rounded-t-md h-5 bg-dark-400 flex items-center justify-start px-2">
<div className="h-2 w-2 mr-2 rounded-full bg-dark-500" />
<div className="h-2 w-2 mr-2 rounded-full bg-dark-500" />
<div className="h-2 w-2 mr-2 rounded-full bg-dark-500" />
</div>
<video className="rounded-b-md" src={src} autoPlay loop muted>
Your browser does not support the video tag
</video>
</div>
)
}
const HamburgerMenu = (props: any) => {
const { openMenu } = props
return (
<div className="cursor-pointer" onClick={openMenu}>
<svg
viewBox="0 0 24 24"
width="24"
height="24"
stroke="white"
strokeWidth="2"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<line x1="3" y1="12" x2="21" y2="12" />
<line x1="3" y1="6" x2="21" y2="6" />
<line x1="3" y1="18" x2="21" y2="18" />
</svg>
</div>
)
}
const SectionHeader = (props: any) => {
const { sectionNumber, header } = props
@@ -44,14 +91,18 @@ const SectionHeader = (props: any) => {
}
const Hero = () => (
<div className="w-screen py-16 lg:py-36 bg-dark-800">
<div className="container mx-auto px-8 lg:px-28 py-20 h-full grid grid-cols-12 gap-4 items-center text-dark-300">
<div className="col-span-12 md:col-span-9 lg:col-span-8 xl:col-span-6 text-2xl text-white">
<p className="mb-10">
Supabase is an opensource Firebase alternative. We're building the features of Firebase
using enterprise-grade, open source tools.
<div
style={{ backgroundImage: "url('images/beta-hero.png')", backgroundSize: "65%", backgroundPosition: "120% 50%"}}
className="w-screen py-16 lg:py-36 bg-dark-800 bg-no-repeat"
>
<div
className="container mx-auto px-8 lg:px-28 py-20 h-full grid grid-cols-12 gap-4 items-center text-dark-300"
>
<div className="col-span-12 md:col-span-9 lg:col-span-8 xl:col-span-6 text-white">
<p className="mb-10 text-4xl">
Supabase is an opensource Firebase alternative.
</p>
<p>
<p className="text-2xl">
Today, we're moving to <span className="text-brand-700">Beta</span>
</p>
</div>
@@ -59,23 +110,29 @@ const Hero = () => (
</div>
)
const Introduction = (props: any) => {
const { scrollTo } = props
const Introduction = () => {
return (
<div className="bg-gray-50 dark:bg-dark-700">
<div className="container mx-auto px-8 lg:px-28 py-20 grid grid-cols-12 gap-4 text-dark-400 dark:text-dark-300">
<div className="col-span-12 sm:col-span-9 xl:col-span-7 text-base mb-20">
<div className="bg-dark-900">
<div className="container mx-auto px-8 lg:px-28 py-20 grid grid-cols-12 gap-4 text-dark-300">
<div className="col-span-12 sm:col-span-9 xl:col-span-8">
<p>
After the launch of our{' '}
<a
href="https://news.ycombinator.com/item?id=23319901"
target="_blank"
className="text-brand-700 hover:text-brand-800"
>
Alpha
</a>{' '}
Program in June, we've been fortunate to work with thousands of early adopters on
improving both our Open Source, and Hosted offerings.
<span className="text-2xl block text-white">
After the launch of our{' '}
<a
href="https://news.ycombinator.com/item?id=23319901"
target="_blank"
className="text-brand-700 hover:text-brand-800"
>
Alpha
</a>{' '}
Program in June,
</span>
</p>
</div>
<div className="col-span-12 sm:col-span-9 xl:col-span-6 text-base mb-20">
<p>
we've been fortunate to work with thousands of early adopters on improving both our Open
Source, and Hosted offerings.
</p>
</div>
@@ -108,7 +165,21 @@ const Introduction = (props: any) => {
</div>
))}
</div>
</div>
</div>
)
}
const TableOfContents = (props: any) => {
const { scrollTo } = props
return (
<div className="bg-gray-50 dark:bg-dark-700 text-dark-400 dark:text-dark-300">
<div className="container mx-auto px-8 lg:px-28 py-20 grid grid-cols-12 gap-4">
<div className="col-span-12 text-base mb-10">
<p className="text-2xl text-black dark:text-white">
Supabase <span className="text-brand-600 dark:text-brand-700">Beta</span> is starting now.
</p>
</div>
<div className="col-span-12 grid grid-cols-12 gap-y-10">
{IntroductionSegments.map((segment: any, segmentIdx: number) => (
<div key={`introSegment_${segmentIdx}`} className="col-span-12 grid grid-cols-12">
@@ -123,10 +194,10 @@ const Introduction = (props: any) => {
className="flex items-center mb-5 cursor-pointer"
onClick={() => scrollTo(chapter.key)}
>
<p className="font-mono text-xs text-dark-300 dark:text-dark-400">{`0${
chapter.no
}`}</p>
<p className="ml-4 transition text-base border-b border-gray-400 hover:text-black">{chapter.name}</p>
<p className="font-mono text-xs text-dark-300 dark:text-dark-400">{`0${chapter.no}`}</p>
<p className="ml-4 transition text-base border-b border-gray-400 hover:text-black">
{chapter.name}
</p>
</div>
))}
</div>
@@ -139,85 +210,36 @@ const Introduction = (props: any) => {
}
const Performance = () => {
const ComparisonChart = () => {
const maxValue = 1600
return (
<div className="grid grid-cols-12 text-dark-400 dark:text-dark-300 items-center">
<div className="col-span-12">
<p className="w-36 pb-2 mb-4">Read (requests/s)</p>
</div>
<div className="col-span-12 sm:col-span-10 grid grid-cols-12">
<div className="col-span-12 grid grid-cols-12 items-center">
<div className="col-span-4 sm:col-span-2 py-2 border-r border-dark-200 dark:border-dark-400 mr-3">
Supabase
</div>
<div className="col-span-9 py-2">
<div
className="bg-brand-600 dark:bg-brand-700 transition-all flex items-center justify-center group rounded-full h-3 hover:h-6"
style={{ width: '100%' }}
>
<p className="transition text-dark-700 opacity-0 group-hover:opacity-100">1167 requests/s</p>
<div>
{PerformanceComparisonData.map((metric: any) => {
const multiplier = (metric.stats[0].value / metric.stats[1].value).toFixed(1)
return (
<div key={`${metric.key}`} className="mb-10 text-dark-400 dark:text-dark-300">
<p className="sm:w-36 pb-2 mb-4">{metric.title}</p>
<div className="flex flex-col sm:flex-row sm:items-center">
<div className="w-full sm:w-5/6">
{metric.stats.map((stat: any, idx: number) => (
<div key={`metric_${metric.key}_${idx}`} className="flex items-center">
<p className="w-20 lg:w-24 border-r py-2 pr-4 mr-4 text-left sm:text-right">{stat.name}</p>
<div
className={`${stat.color} rounded-full h-3 transition-all`}
style={{ width: `calc(${((stat.value / maxValue) * 100)}%)`}}
/>
<p className="ml-2">{stat.value}/s</p>
</div>
))}
</div>
<div className="text-left sm:w-1/6 sm:text-right flex flex-col">
<p className="text-6xl text-dark-700 dark:text-dark-100">{multiplier}x</p>
<p className="text-sm -mt-2">more {metric.key}s per second</p>
</div>
</div>
</div>
<div className="hidden col-span-1 sm:block" />
</div>
<div className="col-span-12 grid grid-cols-12 items-center">
<div className="col-span-4 sm:col-span-2 py-2 border-r border-dark-200 dark:border-dark-400 mr-3">
Firestore
</div>
<div className="col-span-9 py-2">
<div
className="bg-dark-300 dark:bg-dark-400 transition-all flex items-center justify-center group rounded-full h-3 hover:h-6"
style={{ width: '31.36%' }}
>
<p className="transition text-dark-700 opacity-0 group-hover:opacity-100">366 requests/s</p>
</div>
</div>
</div>
</div>
<div className="col-span-12 sm:col-span-2">
<p className="text-6xl text-dark-700 sm:text-right">3.2x</p>
<p className="text-sm sm:text-right -mt-2">faster read requests</p>
</div>
<div className="col-span-12 py-5" />
<div className="col-span-12">
<p className="w-36 pb-2 mb-4">Write (requests/s)</p>
</div>
<div className="col-span-12 sm:col-span-10 grid grid-cols-12">
<div className="col-span-12 grid grid-cols-12 items-center">
<div className="col-span-4 sm:col-span-2 py-2 border-r border-dark-200 dark:border-dark-400 mr-3">
Supabase
</div>
<div className="col-span-9 py-2">
<div
className="bg-brand-600 dark:bg-brand-700 transition-all flex items-center justify-center group rounded-full h-3 hover:h-6"
style={{ width: '74.55%' }}
>
<p className="transition text-dark-700 opacity-0 group-hover:opacity-100">870 requests/s</p>
</div>
</div>
<div className="hidden col-span-1 sm:block" />
</div>
<div className="col-span-12 grid grid-cols-12 items-center">
<div className="col-span-4 sm:col-span-2 py-2 border-r border-dark-200 dark:border-dark-400 mr-3">
Firestore
</div>
<div className="col-span-9 py-2">
<div
className="bg-dark-300 dark:bg-dark-400 transition-all flex items-center justify-center group rounded-full h-3 hover:h-6"
style={{ width: '23.99%' }}
>
<p className="transition text-dark-700 opacity-0 group-hover:opacity-100">280 requests/s</p>
</div>
</div>
</div>
</div>
<div className="col-span-12 sm:col-span-2">
<p className="text-6xl text-dark-700 sm:text-right">3.1x</p>
<p className="text-sm sm:text-right -mt-2">faster write requests</p>
</div>
)
})}
</div>
)
}
@@ -395,8 +417,10 @@ const Reliability = () => (
https://status.supabase.io
</a>{' '}
to keep track of uptime across all of our services and critical infrastructure.
(Possibly drop a screen grab here)
</p>
<div className="mb-10">
<VideoShot src="videos/statusPage.mp4" />
</div>
<p>
For our Alpha & Beta Users we take daily backups of your Database free of charge up to
20GB and store them in an encrypted format. They are available to download at any time
@@ -422,7 +446,7 @@ const NewFeaturesAndIntegrations = () => (
<ul className="">
<li className="mb-10">
<p className="w-20 pb-2 mb-2 border-b-2 border-dark-200 dark:border-dark-400">Auth</p>
<p>
<p className="mb-5">
We provide an easy to use{' '}
<a
href="https://supabase.io/docs/client/auth-signup"
@@ -447,6 +471,7 @@ const NewFeaturesAndIntegrations = () => (
can use to log them into your app, and even offer several OAuth providers including
Google, GitHub, and have more on the way.
</p>
<VideoShot src="videos/tabAuthRules.mp4" />
</li>
<li className="mb-10">
<p className="w-20 pb-2 mb-2 border-b-2 border-dark-200 dark:border-dark-400">
@@ -505,19 +530,21 @@ const NewFeaturesAndIntegrations = () => (
<p className="w-24 pb-2 mb-2 border-b-2 border-dark-200 dark:border-dark-400">
Table View
</p>
<p>
<p className="mb-5">
View and edit your data like a spreadsheet from within the Supabase dashboard,
create complex relationships, import and export to csv.
</p>
<VideoShot src="videos/tabTableEditor.mp4" />
</li>
<li>
<p className="w-24 pb-2 mb-2 border-b-2 border-dark-200 dark:border-dark-400">
SQL Editor
</p>
<p>
<p className="mb-5">
No need to install third party SQL tools, you can run queries directly from the
Supabase Dashbaord.
</p>
<VideoShot src="videos/tabSqlEditor.mp4" />
</li>
</ul>
</div>
@@ -742,7 +769,9 @@ const WhatsNext = () => (
)
const Beta = () => {
const { basePath } = useRouter()
const [ menuOpen, setMenuOpen ] = useState<boolean>(false)
const references: any = {
performance: useRef<HTMLDivElement>(null),
security: useRef<HTMLDivElement>(null),
@@ -781,12 +810,21 @@ const Beta = () => {
<meta name="twitter:image" content="/public/og/og-image.jpg" />
</Head>
<Container>
<div className="shadow-lg py-5 px-5 lg:px-20 sticky inset-0 bg-dark-800 z-50 flex items-center justify-between">
<img className="h-5" src={`${basePath}/images/logo-dark.png`} />
<HamburgerMenu />
<div className="relative shadow-lg py-5 px-5 xl:px-20 sticky inset-0 bg-dark-800 z-50 flex items-center justify-between">
<img className="h-5" src="images/logo-dark.png" />
<HamburgerMenu openMenu={() => setMenuOpen(!menuOpen)}/>
<FlyOut
open={menuOpen}
handleCancel={() => setMenuOpen(false)}
className="lg:col-span-1"
singleBgColor={true}
>
<NavFlyOutMenu scrollTo={scrollTo} />
</FlyOut>
</div>
<Hero />
<Introduction scrollTo={scrollTo} />
<Introduction />
<TableOfContents scrollTo={scrollTo} />
<div ref={references['performance']}>
<Performance />
</div>
Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.