diff --git a/www/components/CodeBlock/CodeBlock.module.css b/www/components/CodeBlock/CodeBlock.module.css index dd03e06097d..364e15058e9 100644 --- a/www/components/CodeBlock/CodeBlock.module.css +++ b/www/components/CodeBlock/CodeBlock.module.css @@ -3,6 +3,7 @@ } .code-line { + @apply block; transition: filter 500ms ease, opacity 500ms ease; transition-delay: 200ms; } @@ -39,3 +40,7 @@ .code-block code::before { content: none !important; } + +.code-line--flash { + @apply animate-flash-code-slow; +} diff --git a/www/components/CodeBlock/CodeBlock.tsx b/www/components/CodeBlock/CodeBlock.tsx index bd6e7e723c9..e27c24973e1 100644 --- a/www/components/CodeBlock/CodeBlock.tsx +++ b/www/components/CodeBlock/CodeBlock.tsx @@ -6,6 +6,8 @@ import { Button, IconCopy } from '@supabase/ui' import CopyToClipboard from 'react-copy-to-clipboard' import rangeParser from 'parse-numeric-range' +import classNames from 'classnames' + import js from 'react-syntax-highlighter/dist/cjs/languages/hljs/javascript' import ts from 'react-syntax-highlighter/dist/cjs/languages/hljs/typescript' import py from 'react-syntax-highlighter/dist/cjs/languages/hljs/python' @@ -61,7 +63,13 @@ function CodeBlock(props: CodeBlockProps) { const style = shouldHighlightLine ? {} : { filter: 'grayscale(75%)', opacity: 0.5 } - return { class: CodeBlockStyles['code-line'], style } + return { + class: classNames( + CodeBlockStyles['code-line'], + shouldHighlightLine && CodeBlockStyles['code-line--flash'] + ), + style, + } }, [highlightLines] ) diff --git a/www/pages/edge-functions/edge-functions.tsx b/www/pages/edge-functions/edge-functions.tsx index 00536fc0264..ba9ea9be7d3 100644 --- a/www/pages/edge-functions/edge-functions.tsx +++ b/www/pages/edge-functions/edge-functions.tsx @@ -40,11 +40,11 @@ import TweetCard from '~/components/TweetCard' // install Swiper's Controller component // SwiperCore.use([Controller]) -const featureHighlights = [ +const featureBlocks = [ { title: 'Title of thing', description: 'Title of thing adasd adsdsdasdasd dsadasda adsdds', - highlightLines: '1..8', + highlightLines: '8', }, { title: 'Title of thing', @@ -61,6 +61,46 @@ const featureHighlights = [ description: 'Title of thing adasd adsdsdasdasd dsadasda adsdds', highlightLines: '31', }, + { + title: 'Title of thing', + description: 'Title of thing adasd adsdsdasdasd dsadasda adsdds', + highlightLines: '31', + }, + { + title: 'Title of thing', + description: 'Title of thing adasd adsdsdasdasd dsadasda adsdds', + highlightLines: '31', + }, +] + +const featureHighlights = [ + { + title: 'Run a function from anywhere', + description: `It's as easy as running serve()`, + highlightLines: '1,5', + }, + { + title: 'Set authentication', + description: 'Use the JWT token to set the authentication of the user', + highlightLines: '15..20', + }, + { + title: 'Use anything from Supabase', + description: + 'supabase-js can interact with any part of the Supabase stack from Edge Functions, while respecting auth row level security policies.', + highlightLines: '22..27', + }, + { + title: 'Use secrets to store senstive keys', + description: + 'Set and edit secrets via the CLI, which can then be accessed via enviroment variables.', + highlightLines: '7..13', + }, + { + title: 'No limits', + description: `You're can empowered to run whatever logic you like using any data from the Supabase database.`, + highlightLines: '29..39', + }, ] function Database() { @@ -130,10 +170,10 @@ function Database() {
-
+
-

Anatomy of the Edge

+

Anatomy of the Edge

Create asynchronous tasks within minutes using Supabase Functions with easy access to the rest of the Supabase Ecosystem. @@ -146,16 +186,32 @@ function Database() { ) @@ -165,58 +221,50 @@ function Database() {

- {`import { serve } from "https://deno.land/std@0.131.0/http/server.ts"; -import { stripe } from "../_utils/stripe.ts"; + {`import { serve } from 'https://deno.land/std@0.131.0/http/server.ts' +import Stripe from 'https://esm.sh/stripe?target=deno&no-check' +import { Customer } from 'types' serve(async (req) => { try { - // Get the authorization header from the request. - // When you invoke the function via the client library it will automatically pass the authenticated user's JWT. - const authHeader = req.headers.get("Authorization")!; - - // Create a Supabase client with the Auth context of the logged in user. + // create a supabase client const supabaseClient = createClient( - // Supabase API URL - env var exported by default. - Deno.env.get("SUPABASE_URL") ?? "", - // Supabase API ANON KEY - env var exported by default. - Deno.env.get("SUPABASE_ANON_KEY") ?? "", - // Create client with Auth context of the user that called the function. - // This way your row-level-security (RLS) policies are applied. - { headers: { Authorization: authHeader } } - ); + Deno.env.get('SUPABASE_URL') ?? '', + Deno.env.get('SUPABASE_ANON_KEY') ?? '' + ) + // create a stripe client + const stripe = Stripe(Deno.env.get('STRIPE_SECRET_KEY')) + // Get the authorization header from the request. + const authHeader = req.headers.get('Authorization')! + // Client now respects auth policies for this user supabaseClient.auth.setAuth(authHeader) + // set the user profile + const user = supabase.auth.user() - // Check if the user already has a Stripe customer ID in the Database. + // Retrieve user metadata that only the user is allowed to select const { data, error } = await supabaseClient - .from("customers") - .select("*"); - console.log(data?.length, data, error); - if (error) throw error; - if (data?.length === 1) { - // Exactly one customer found, return it. - const customer = data[0].stripe_customer_id; - console.log(\`Found customer id: \${customer}\`); - return customer; - } + .from('user_profiles') + .select('address, tax, billing_email, phone') - // Create a PaymentIntent so that the SDK can charge the logged in customer. - const paymentIntent = await stripe.paymentIntents.create({ - amount: 1099, - currency: "usd", - customer: customer, - }); + if (error) throw error - - return new Response(JSON.stringify(res), { status: 200 }); + const customer = await stripe.customers.create({ + description: 'My First Stripe Customer (created by a Supabase edge function)', + phone: data.phone, + address: data.address, + email: user.email, + }) + + return new Response(JSON.stringify(customer), { status: 200 }) } catch (error) { - return new Response(JSON.stringify(error), { status: 400 }); + return new Response(JSON.stringify(error), { status: 400 }) } -});`} +})`}
@@ -231,7 +279,7 @@ serve(async (req) => {
- {featureHighlights.map((item) => { + {featureBlocks.map((item) => { return (
diff --git a/www/tailwind.config.js b/www/tailwind.config.js index 1806eb442ee..c44a76c3378 100644 --- a/www/tailwind.config.js +++ b/www/tailwind.config.js @@ -221,6 +221,16 @@ module.exports = ui({ )}">` )}")`, }), + keyframes: { + 'flash-code': { + '0%': { backgroundColor: 'rgb(125 211 252 / 0.1)' }, + '100%': { backgroundColor: 'transparent' }, + }, + }, + animation: { + 'flash-code': 'flash-code 1s ease', + 'flash-code-slow': 'flash-code 2s ease', + }, }, }, // variants: {