Skip to content

Commit 886d744

Browse files
committed
Added: README.md, minor optimizations
1 parent 0b9de68 commit 886d744

File tree

6 files changed

+78
-28
lines changed

6 files changed

+78
-28
lines changed

.env.example

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
NODE_ENV=development
22
AWS_S3_REGION=us-east-1
3-
AWS_S3_BUCKET_NAME=<REPLACE THIS>
4-
AWS_ACCESS_KEY_ID=<REPLACE THIS>
5-
AWS_SECRET_ACCESS_KEY=<REPLACE THIS>
6-
AWS_CLOUDFRONT_DISTRIBUTION=<REPLACE THIS>
3+
AWS_S3_BUCKET_NAME=your-bucket-name
4+
AWS_ACCESS_KEY_ID=key
5+
AWS_SECRET_ACCESS_KEY=secret
6+
AWS_CLOUDFRONT_DISTRIBUTION=abcdef12345678.cloudfront.net

README.md

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,51 @@
1-
# Asset Uploader
1+
# S3 Asset Uploader with Sharp optimization
2+
3+
Simple S3 image asset uploader with Sharp optimization. It is very simple and barebones, but it does the job.
4+
- In future I plan to extend this to also support videos and documents.
5+
6+
Run it on localhost to optimize and upload images to S3. Retrieved links of uploaded images point to Cloudfront and can be used in production.
7+
8+
## Preview
9+
<img src="assets/preview.png" alt="App Preview" width="800"/>
10+
11+
## Pre-requisites
12+
13+
1) Setup S3 bucket with Cloudfront distribution in front of it. This app returns Cloudfront links after you upload the image. [This video](https://www.youtube.com/watch?v=kbI7kRWAU-w) can help you with that.
14+
2) Create IAM user with following policy (replace "your-bucket-name" with your actual bucket name)
15+
```
16+
{
17+
"Version": "2012-10-17",
18+
"Statement": [
19+
{
20+
"Effect": "Allow",
21+
"Action": [
22+
"s3:GetObject",
23+
"s3:PutObject",
24+
"s3:ListBucket"
25+
],
26+
"Resource": [
27+
"arn:aws:s3:::your-bucket-name",
28+
"arn:aws:s3:::your-bucket-name/*"
29+
]
30+
}
31+
]
32+
}
33+
```
34+
35+
## How to setup
36+
1) Download or git clone this repo
37+
2) Create .env file based on .env.example and place it in the root of the project
38+
- The region needs to be us-east-1 for Cloudfront to work (it is global, but according to AWS it has to be configured in us-east-1)
39+
3) Run `npm run install` or `yarn install` or `pnpm install` (I use pnpm, but other package managers should work too)
40+
4) Run `npm run dev` or `yarn dev` or `pnpm dev` to start the server
41+
5) Open your browser and go to `http://localhost:3010`
42+
43+
## How to use
44+
1) **Run it on localhost** <small>(npm run dev)</small>
45+
- <small>#1 Optimization Form</small>
46+
2) **Select image from filesystem**
47+
3) **Fill in quality and size** <small>(at least height or width has to be filled in, Sharp will calculate the other parameter automatically)</small>
48+
4) **Click optimize** <small>-> optimized image will be previewed in the Upload Form</small>
49+
- <small>#2 Upload Form</small>
50+
5) **Fill in the new image name** (technically S3 namespace) <small>-> it will be automatically prefixed with assets/images/</small>
51+
6) **Click upload** <small>-> image will be uploaded to S3 bucket and Cloudfront link will be returned</small>

assets/preview.png

697 KB
Loading

package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
2-
"name": "asset-uploader-frontend",
3-
"version": "0.1.0",
2+
"name": "asset-uploader",
3+
"version": "1.0.0",
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"dev": "next dev",
7+
"dev": "next dev -p 3010",
88
"build": "next build",
99
"start": "next start",
1010
"lint": "next lint"
@@ -31,6 +31,5 @@
3131
"prettier-plugin-tailwindcss": "^0.6.6",
3232
"tailwindcss": "^3.4.1",
3333
"typescript": "^5"
34-
},
35-
"packageManager": "[email protected]"
34+
}
3635
}

src/app/api/objects/route.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export async function GET() {
1919
};
2020

2121
const data = await s3Client.send(new ListObjectsV2Command(params));
22-
console.log(data);
2322
const objects = data.Contents
2423
? data.Contents.map((item) => {
2524
const sizeInKB =

src/app/page.tsx

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,25 @@ export default function Home() {
2424

2525
return (
2626
<main className="flex w-full justify-center py-[20px]">
27-
<div className="flex w-[1680px] justify-between">
28-
<div className="w-[400px]">
29-
<ImageOptimizeForm
30-
key={resetKey} // Reset form when key changes
31-
setPreviewUrl={setPreviewUrl}
32-
setImageInfo={setImageInfo}
33-
/>
34-
</div>
35-
<div className="w-[400px]">
36-
<ImageUploadForm
37-
previewUrl={previewUrl}
38-
imageInfo={imageInfo}
39-
onReset={handleReset} // Call handleReset after upload
40-
/>
41-
</div>
42-
<div className="w-[800px]">
43-
<ObjectList />
27+
<div className="flex w-full max-w-[1680px] justify-center px-[20px]">
28+
<div className="flex w-full max-w-[1640px] gap-[20px]">
29+
<div className="w-[400px] flex-shrink-0">
30+
<ImageOptimizeForm
31+
key={resetKey} // Reset form when key changes
32+
setPreviewUrl={setPreviewUrl}
33+
setImageInfo={setImageInfo}
34+
/>
35+
</div>
36+
<div className="w-[400px] flex-shrink-0">
37+
<ImageUploadForm
38+
previewUrl={previewUrl}
39+
imageInfo={imageInfo}
40+
onReset={handleReset} // Call handleReset after upload
41+
/>
42+
</div>
43+
<div className="min-w-[400px] max-w-[800px] flex-grow">
44+
<ObjectList />
45+
</div>
4446
</div>
4547
</div>
4648
</main>

0 commit comments

Comments
 (0)