diff --git a/.env.example b/.env.example
index 6e082f29..979bb375 100644
--- a/.env.example
+++ b/.env.example
@@ -5,6 +5,15 @@ EMAIL_FROM=
EMAIL_URL=
EMAIL_TOKEN=
+NEXT_PUBLIC_STORAGE_URL=
+NEXT_PUBLIC_AVATAR_BUCKET_NAME=
+
+S3_REGION=
+S3_ENDPOINT=
+S3_ENDPOINT=
+S3_ACCESS_KEY_ID=
+S3_SECRET_ACCESS_KEY=
+
BETTER_AUTH_SECRET=
BETTER_AUTH_URL=
diff --git a/apps/web/package.json b/apps/web/package.json
index 8f79592c..8dc6d3a6 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -14,6 +14,8 @@
"with-env": "dotenv -e ../../.env --"
},
"dependencies": {
+ "@aws-sdk/client-s3": "^3.802.0",
+ "@aws-sdk/s3-presigned-post": "^3.802.0",
"@headlessui/react": "^2.2.0",
"@hookform/resolvers": "^3.3.4",
"@kan/api": "workspace:*",
@@ -26,9 +28,12 @@
"@trpc/next": "^11.0.0-rc.660",
"@trpc/react-query": "catalog:",
"@trpc/server": "catalog:",
+ "@types/uuid": "^10.0.0",
+ "aws-sdk": "^2.1692.0",
"date-fns": "^4.1.0",
"geist": "^1.3.1",
"js-cookie": "^3.0.5",
+ "jwt-decode": "^4.0.0",
"next": "^14.2.15",
"nextjs-cors": "^2.2.0",
"react": "catalog:react18",
diff --git a/apps/web/src/components/UserMenu.tsx b/apps/web/src/components/UserMenu.tsx
index 31ba9bde..5e681b24 100644
--- a/apps/web/src/components/UserMenu.tsx
+++ b/apps/web/src/components/UserMenu.tsx
@@ -6,6 +6,7 @@ import { Fragment } from "react";
import { authClient } from "@kan/auth";
import { useTheme } from "~/providers/theme";
+import { getAvatarUrl } from "~/utils/helpers";
interface UserMenuProps {
imageUrl: string | undefined;
@@ -31,8 +32,7 @@ export default function UserMenu({
router.push("/login");
};
- // const avatarUrl = imageUrl ? getPublicUrl(imageUrl) : null;
- const avatarUrl = "";
+ const avatarUrl = imageUrl ? getAvatarUrl(imageUrl) : null;
return (