[resumes][fix] process file transfer over next.js

pull/321/head
Keane Chan 3 years ago
parent 498b0b0a28
commit 6a58342b38
No known key found for this signature in database
GPG Key ID: 32718398E1E9F87C

@ -22,8 +22,10 @@
"@trpc/next": "^9.27.2",
"@trpc/react": "^9.27.2",
"@trpc/server": "^9.27.2",
"axios": "^1.1.2",
"clsx": "^1.2.1",
"date-fns": "^2.29.3",
"formidable": "^2.0.1",
"next": "12.3.1",
"next-auth": "~4.10.3",
"react": "18.2.0",
@ -38,6 +40,7 @@
"devDependencies": {
"@tih/tailwind-config": "*",
"@tih/tsconfig": "*",
"@types/formidable": "^2.0.5",
"@types/node": "^18.0.0",
"@types/react": "^18.0.21",
"@types/react-dom": "^18.0.6",

@ -12,6 +12,8 @@ export const serverSchema = z.object({
NEXTAUTH_SECRET: z.string(),
NEXTAUTH_URL: z.string().url(),
NODE_ENV: z.enum(['development', 'test', 'production']),
SUPABASE_ANON_KEY: z.string(),
SUPABASE_URL: z.string().url(),
});
/**
@ -20,8 +22,7 @@ export const serverSchema = z.object({
* To expose them to the client, prefix them with `NEXT_PUBLIC_`.
*/
export const clientSchema = z.object({
NEXT_PUBLIC_SUPABASE_ANON_KEY: z.string(),
NEXT_PUBLIC_SUPABASE_URL: z.string().url(),
// NEXT_PUBLIC_BAR: z.string(),
});
/**
@ -32,6 +33,4 @@ export const clientSchema = z.object({
*/
export const clientEnv = {
// NEXT_PUBLIC_BAR: process.env.NEXT_PUBLIC_BAR,
NEXT_PUBLIC_SUPABASE_ANON_KEY: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
NEXT_PUBLIC_SUPABASE_URL: process.env.NEXT_PUBLIC_SUPABASE_URL,
};

@ -0,0 +1,59 @@
import axios from 'axios';
import { formidable } from 'formidable';
import type { NextApiRequest, NextApiResponse } from 'next';
import { v4 as uuidv4 } from 'uuid';
import { env } from '~/env/server.mjs';
const BASE_URL = `${env.SUPABASE_URL}/storage/v1/object`;
export const config = {
api: {
bodyParser: false,
},
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
const headers = {
'Content-Type': 'multipart/form-data',
apiKey: env.SUPABASE_ANON_KEY,
authorization: 'Bearer ' + env.SUPABASE_ANON_KEY,
};
if (req.method === 'POST') {
try {
const form = formidable({ multiples: false });
form.parse(req, async (err, fields, files) => {
if (err) {
throw err;
}
const { file } = files;
const actualFile = file instanceof Array ? file[0] : file;
const filePath = `${uuidv4()}-${actualFile.originalFilename}`;
const { key } = fields;
const data = await axios.post(
`${BASE_URL}/${key}/${filePath}`,
actualFile,
{
headers,
},
);
return res.status(200).json({
url: data.data.key,
});
});
} catch (error: unknown) {
return Promise.reject(error);
}
}
if (req.method === 'GET') {
const { key, filePath } = req.query;
const data = await axios.get(`${BASE_URL}/public/${key}/${filePath}`);
res.status(200).json(data);
}
}

@ -1,10 +1,10 @@
import axios from 'axios';
import clsx from 'clsx';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { useMemo, useState } from 'react';
import type { SubmitHandler } from 'react-hook-form';
import { useForm } from 'react-hook-form';
import { v4 as uuidv4 } from 'uuid';
import { PaperClipIcon } from '@heroicons/react/24/outline';
import { Button, Select, TextArea, TextInput } from '@tih/ui';
@ -14,7 +14,6 @@ import {
ROLES,
} from '~/components/resumes/browse/constants';
import { supabase } from '~/utils/supabaseClient';
import { trpc } from '~/utils/trpc';
const TITLE_PLACEHOLDER =
@ -55,21 +54,25 @@ export default function SubmitResumeForm() {
return;
}
const formData = new FormData();
formData.append('key', 'resumes');
formData.append('file', resumeFile);
// Prefix with uuid so that it is always unique
const url = `${uuidv4()}-${resumeFile.name}`;
const { error } = await supabase.storage
.from('resumes')
.upload(url, resumeFile);
const res = await axios.post('/api/file-storage', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
if (error) {
console.error(error);
}
const { url } = res.data;
await resumeCreateMutation.mutate({
...data,
url,
});
router.push('/resumes');
// Router.push('/resumes');
reset();
};
const onUploadFile = (event: React.ChangeEvent<HTMLInputElement>) => {

@ -1,8 +0,0 @@
import { createClient } from '@supabase/supabase-js';
import { env } from '~/env/client.mjs';
const supabaseUrl = env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseAnonKey = env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
export const supabase = createClient(supabaseUrl, supabaseAnonKey);

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save