Skip to content

Commit 75eafc8

Browse files
committed
use supabase to store the images
1 parent a3340d8 commit 75eafc8

File tree

9 files changed

+539
-42
lines changed

9 files changed

+539
-42
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
},
1212
"dependencies": {
1313
"@emotion/react": "^11.8.2",
14+
"@supabase/supabase-js": "^2.45.4",
1415
"@types/express-useragent": "^1.0.2",
1516
"@types/jwk-to-pem": "^2.0.1",
1617
"@types/node-jose": "^1.1.10",

pages/index.tsx

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import useScreenSize from '../utils/useScreenSize';
3535
import toBase64 from '../utils/toBase64';
3636
import { isRunningAcceptanceTest } from '../utils/testUtils';
3737

38+
import { createClient } from '@supabase/supabase-js';
39+
3840
import { Transition } from 'react-transition-group';
3941

4042
import { useEffect, useMemo, useRef, useState } from 'react';
@@ -1010,47 +1012,55 @@ export async function getServerSideProps() {
10101012
};
10111013
}
10121014

1013-
const response = await getImageData();
1015+
const supabaseUrl = process.env.SUPABASE_NEXT_PUBLIC_SUPABASE_URL || ' ';
1016+
const supabaseAnonKey =
1017+
process.env.SUPABASE_NEXT_PUBLIC_SUPABASE_ANON_KEY || '';
10141018

1015-
if (!response) {
1016-
return [];
1019+
const supabase = createClient(supabaseUrl, supabaseAnonKey, {
1020+
global: {
1021+
headers: {
1022+
Authorization: `Bearer ${process.env.SUPABASE_SUPABASE_SERVICE_ROLE_KEY}`,
1023+
},
1024+
},
1025+
});
1026+
const { data, error } = await supabase
1027+
.from('gallery-images')
1028+
.select('url, name, height, width')
1029+
.limit(30)
1030+
.order('created_at', { ascending: false });
1031+
1032+
if (data === null) {
1033+
throw new Error(error?.message);
10171034
}
10181035

1019-
const images = response.map(
1020-
(photo: {
1021-
contentProperties: { image: { height: number; width: number } };
1022-
url: string;
1023-
name: string;
1024-
}) => {
1025-
const { height: originalHeight, width: originalWidth } =
1026-
photo.contentProperties.image;
1027-
const dimensionsRatio = originalHeight / originalWidth;
1028-
const thumbnailFitWidth =
1029-
originalHeight > 200
1030-
? [200, 200 / dimensionsRatio]
1031-
: [originalHeight, originalWidth];
1032-
const thumbnailFit =
1033-
originalWidth > 150
1034-
? [thumbnailFitWidth[0] * dimensionsRatio, 150]
1035-
: thumbnailFitWidth;
1036-
1037-
return {
1038-
src: photo.url,
1039-
name: photo.name,
1040-
dimensions: {
1041-
ratio: dimensionsRatio,
1042-
thumbnail: {
1043-
height: thumbnailFit[0],
1044-
width: thumbnailFit[1],
1045-
},
1046-
original: {
1047-
height: originalHeight,
1048-
width: originalWidth,
1049-
},
1036+
const images = data.map((photo) => {
1037+
const { height: originalHeight, width: originalWidth } = photo;
1038+
const dimensionsRatio = originalHeight / originalWidth;
1039+
const thumbnailFitWidth =
1040+
originalHeight > 200
1041+
? [200, 200 / dimensionsRatio]
1042+
: [originalHeight, originalWidth];
1043+
const thumbnailFit =
1044+
originalWidth > 150
1045+
? [thumbnailFitWidth[0] * dimensionsRatio, 150]
1046+
: thumbnailFitWidth;
1047+
1048+
return {
1049+
src: photo.url,
1050+
name: photo.name,
1051+
dimensions: {
1052+
ratio: dimensionsRatio,
1053+
thumbnail: {
1054+
height: thumbnailFit[0],
1055+
width: thumbnailFit[1],
10501056
},
1051-
};
1052-
}
1053-
);
1057+
original: {
1058+
height: originalHeight,
1059+
width: originalWidth,
1060+
},
1061+
},
1062+
};
1063+
});
10541064

10551065
return {
10561066
props: {

supabase/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Supabase
2+
.branches
3+
.temp
4+
.env

supabase/config.toml

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# A string used to distinguish different Supabase projects on the same host. Defaults to the
2+
# working directory name when running `supabase init`.
3+
project_id = "bertuz.github.io"
4+
5+
[api]
6+
enabled = true
7+
# Port to use for the API URL.
8+
port = 54321
9+
# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API
10+
# endpoints. public and storage are always included.
11+
schemas = ["public", "storage", "graphql_public"]
12+
# Extra schemas to add to the search_path of every request. public is always included.
13+
extra_search_path = ["public", "extensions"]
14+
# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size
15+
# for accidental or malicious requests.
16+
max_rows = 1000
17+
18+
[db]
19+
# Port to use for the local database URL.
20+
port = 54322
21+
# Port used by db diff command to initialize the shadow database.
22+
shadow_port = 54320
23+
# The database major version to use. This has to be the same as your remote database's. Run `SHOW
24+
# server_version;` on the remote database to check.
25+
major_version = 15
26+
27+
[db.pooler]
28+
enabled = false
29+
# Port to use for the local connection pooler.
30+
port = 54329
31+
# Specifies when a server connection can be reused by other clients.
32+
# Configure one of the supported pooler modes: `transaction`, `session`.
33+
pool_mode = "transaction"
34+
# How many server connections to allow per user/database pair.
35+
default_pool_size = 20
36+
# Maximum number of client connections allowed.
37+
max_client_conn = 100
38+
39+
[realtime]
40+
enabled = true
41+
# Bind realtime via either IPv4 or IPv6. (default: IPv6)
42+
# ip_version = "IPv6"
43+
# The maximum length in bytes of HTTP request headers. (default: 4096)
44+
# max_header_length = 4096
45+
46+
[studio]
47+
enabled = true
48+
# Port to use for Supabase Studio.
49+
port = 54323
50+
# External URL of the API server that frontend connects to.
51+
api_url = "http://127.0.0.1"
52+
# OpenAI API Key to use for Supabase AI in the Supabase Studio.
53+
openai_api_key = "env(OPENAI_API_KEY)"
54+
55+
# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they
56+
# are monitored, and you can view the emails that would have been sent from the web interface.
57+
[inbucket]
58+
enabled = true
59+
# Port to use for the email testing server web interface.
60+
port = 54324
61+
# Uncomment to expose additional ports for testing user applications that send emails.
62+
# smtp_port = 54325
63+
# pop3_port = 54326
64+
65+
[storage]
66+
enabled = true
67+
# The maximum file size allowed (e.g. "5MB", "500KB").
68+
file_size_limit = "50MiB"
69+
70+
[auth]
71+
enabled = true
72+
# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
73+
# in emails.
74+
site_url = "http://127.0.0.1:3000"
75+
# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
76+
additional_redirect_urls = ["https://127.0.0.1:3000"]
77+
# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
78+
jwt_expiry = 3600
79+
# If disabled, the refresh token will never expire.
80+
enable_refresh_token_rotation = true
81+
# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds.
82+
# Requires enable_refresh_token_rotation = true.
83+
refresh_token_reuse_interval = 10
84+
# Allow/disallow new user signups to your project.
85+
enable_signup = true
86+
# Allow/disallow testing manual linking of accounts
87+
enable_manual_linking = false
88+
89+
[auth.email]
90+
# Allow/disallow new user signups via email to your project.
91+
enable_signup = true
92+
# If enabled, a user will be required to confirm any email change on both the old, and new email
93+
# addresses. If disabled, only the new email is required to confirm.
94+
double_confirm_changes = true
95+
# If enabled, users need to confirm their email address before signing in.
96+
enable_confirmations = false
97+
98+
# Uncomment to customize email template
99+
# [auth.email.template.invite]
100+
# subject = "You have been invited"
101+
# content_path = "./supabase/templates/invite.html"
102+
103+
[auth.sms]
104+
# Allow/disallow new user signups via SMS to your project.
105+
enable_signup = true
106+
# If enabled, users need to confirm their phone number before signing in.
107+
enable_confirmations = false
108+
# Template for sending OTP to users
109+
template = "Your code is {{ .Code }} ."
110+
111+
# Use pre-defined map of phone number to OTP for testing.
112+
[auth.sms.test_otp]
113+
# 4152127777 = "123456"
114+
115+
# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used.
116+
[auth.hook.custom_access_token]
117+
# enabled = true
118+
# uri = "pg-functions://<database>/<schema>/<hook_name>"
119+
120+
121+
# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`.
122+
[auth.sms.twilio]
123+
enabled = false
124+
account_sid = ""
125+
message_service_sid = ""
126+
# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead:
127+
auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)"
128+
129+
# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`,
130+
# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`,
131+
# `twitter`, `slack`, `spotify`, `workos`, `zoom`.
132+
[auth.external.apple]
133+
enabled = false
134+
client_id = ""
135+
# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead:
136+
secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)"
137+
# Overrides the default auth redirectUrl.
138+
redirect_uri = ""
139+
# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure,
140+
# or any other third-party OIDC providers.
141+
url = ""
142+
143+
[analytics]
144+
enabled = false
145+
port = 54327
146+
vector_port = 54328
147+
# Configure one of the supported backends: `postgres`, `bigquery`.
148+
backend = "postgres"
149+
150+
# Experimental features may be deprecated any time
151+
[experimental]
152+
# Configures Postgres storage engine to use OrioleDB (S3)
153+
orioledb_version = ""
154+
# Configures S3 bucket URL, eg. <bucket_name>.s3-<region>.amazonaws.com
155+
s3_host = "env(S3_HOST)"
156+
# Configures S3 bucket region, eg. us-east-1
157+
s3_region = "env(S3_REGION)"
158+
# Configures AWS_ACCESS_KEY_ID for S3 bucket
159+
s3_access_key = "env(S3_ACCESS_KEY)"
160+
# Configures AWS_SECRET_ACCESS_KEY for S3 bucket
161+
s3_secret_key = "env(S3_SECRET_KEY)"
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { createClient } from 'jsr:@supabase/supabase-js@2';
2+
import sizeOf from 'npm:buffer-image-size';
3+
4+
import { Buffer } from 'node:buffer';
5+
6+
const SUPABASE_DOMAIN = 'https://fpbswrebvsmjdwekyznx.supabase.co';
7+
const IMAGES_URL = `${SUPABASE_DOMAIN}/storage/v1/object/public/photos`;
8+
9+
Deno.serve(async (req) => {
10+
const { 'new-image': image } = await req.json();
11+
12+
const { name: nameWithExtension, id } = image;
13+
const name = nameWithExtension.replace(/\.[a-zA-Z0-9]{1,3}$/, '');
14+
const url = `${IMAGES_URL}/${nameWithExtension}`;
15+
const contentImage = await fetch(url, {
16+
method: 'GET',
17+
});
18+
const imageBuffer = Buffer.from(await contentImage.arrayBuffer());
19+
const imageSize = sizeOf(imageBuffer);
20+
21+
const dataToSend = {
22+
id,
23+
url,
24+
height: imageSize.height,
25+
width: imageSize.width,
26+
name,
27+
};
28+
console.log(dataToSend);
29+
console.log(req.headers.get('Authorization'));
30+
31+
const supabaseClient = createClient(
32+
Deno.env.get('SUPABASE_URL') ?? '',
33+
Deno.env.get('SUPABASE_ANON_KEY') ?? '',
34+
{
35+
global: { headers: { Authorization: req.headers.get('Authorization')! } },
36+
}
37+
);
38+
39+
const { data, error } = await supabaseClient
40+
.from('gallery-images')
41+
.insert(dataToSend);
42+
console.log(data);
43+
console.log(error);
44+
console.log(` inserted image data ${data}, error (if any): ${error}`);
45+
46+
return new Response(JSON.stringify('Gotcha'), {
47+
headers: { 'Content-Type': 'application/json' },
48+
});
49+
});

0 commit comments

Comments
 (0)