feat: implement internal auth user creation and update related functionalities
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
type ProjectFinanceItem,
|
||||
type ProjectPlanningSectionItem,
|
||||
} from "@/app/(dashboard)/projects/[id]/project-detail-client";
|
||||
import { createServiceRoleClient } from "@/lib/supabase/admin";
|
||||
import { createClient } from "@/lib/supabase/server";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
@@ -105,7 +106,7 @@ export default async function ProjectDetailPage({
|
||||
|
||||
const projectData = projectRow as unknown as ProjectRow;
|
||||
const coverImageUrl = projectData.cover_image_path
|
||||
? await createProjectImageUrl(supabase, projectData.cover_image_path)
|
||||
? await createProjectImageUrl(projectData.cover_image_path)
|
||||
: null;
|
||||
|
||||
const project: ProjectDetail = {
|
||||
@@ -165,11 +166,9 @@ export default async function ProjectDetailPage({
|
||||
);
|
||||
}
|
||||
|
||||
async function createProjectImageUrl(
|
||||
supabase: Awaited<ReturnType<typeof createClient>>,
|
||||
path: string,
|
||||
) {
|
||||
const { data } = await supabase.storage
|
||||
async function createProjectImageUrl(path: string) {
|
||||
const admin = createServiceRoleClient();
|
||||
const { data } = await admin.storage
|
||||
.from("project-assets")
|
||||
.createSignedUrl(path, 60 * 15);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use server";
|
||||
|
||||
import { createClient } from "@/lib/supabase/server";
|
||||
import { createServiceRoleClient } from "@/lib/supabase/admin";
|
||||
import { randomUUID } from "crypto";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
@@ -114,12 +115,10 @@ function sanitizeFileName(name: string) {
|
||||
}
|
||||
|
||||
async function uploadCoverImage({
|
||||
supabase,
|
||||
userId,
|
||||
projectId,
|
||||
formData,
|
||||
}: {
|
||||
supabase: Awaited<ReturnType<typeof createClient>>;
|
||||
userId: string;
|
||||
projectId: string;
|
||||
formData: FormData;
|
||||
@@ -132,7 +131,8 @@ async function uploadCoverImage({
|
||||
|
||||
const fileName = `${Date.now()}-${sanitizeFileName(file.name) || "cover-image"}`;
|
||||
const path = `${userId}/projects/${projectId}/${fileName}`;
|
||||
const { error } = await supabase.storage
|
||||
const admin = createServiceRoleClient();
|
||||
const { error } = await admin.storage
|
||||
.from(PROJECT_ASSETS_BUCKET)
|
||||
.upload(path, file, {
|
||||
cacheControl: "3600",
|
||||
@@ -157,7 +157,6 @@ export async function createProjectRecord(formData: FormData) {
|
||||
}
|
||||
|
||||
const coverImagePath = await uploadCoverImage({
|
||||
supabase,
|
||||
userId,
|
||||
projectId,
|
||||
formData,
|
||||
@@ -187,7 +186,6 @@ export async function updateProjectRecord(formData: FormData) {
|
||||
}
|
||||
|
||||
const coverImagePath = await uploadCoverImage({
|
||||
supabase,
|
||||
userId,
|
||||
projectId: id,
|
||||
formData,
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
type ProjectListItem,
|
||||
} from "@/app/(dashboard)/projects/projects-client";
|
||||
import { createClient } from "@/lib/supabase/server";
|
||||
import { createServiceRoleClient } from "@/lib/supabase/admin";
|
||||
|
||||
type ProjectRow = {
|
||||
id: string;
|
||||
@@ -59,7 +60,6 @@ export default async function ProjectsPage() {
|
||||
const taskStats = countTasksByProject((taskRows || []) as TaskRow[]);
|
||||
const clients = (clientRows || []) as ProjectClientOption[];
|
||||
const signedUrls = await createProjectImageUrls(
|
||||
supabase,
|
||||
((projectRows || []) as unknown as ProjectRow[])
|
||||
.map((project) => project.cover_image_path)
|
||||
.filter(Boolean) as string[],
|
||||
@@ -93,15 +93,15 @@ export default async function ProjectsPage() {
|
||||
}
|
||||
|
||||
async function createProjectImageUrls(
|
||||
supabase: Awaited<ReturnType<typeof createClient>>,
|
||||
paths: string[],
|
||||
) {
|
||||
const admin = createServiceRoleClient();
|
||||
const urls = new Map<string, string>();
|
||||
const uniquePaths = Array.from(new Set(paths));
|
||||
|
||||
await Promise.all(
|
||||
uniquePaths.map(async (path) => {
|
||||
const { data } = await supabase.storage
|
||||
const { data } = await admin.storage
|
||||
.from("project-assets")
|
||||
.createSignedUrl(path, 60 * 15);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
toast,
|
||||
} from "poyraz-ui/molecules";
|
||||
import {
|
||||
CalendarDays,
|
||||
@@ -398,6 +399,13 @@ function ProjectDialog({
|
||||
try {
|
||||
await action(formData);
|
||||
setOpen(false);
|
||||
toast.success(mode === "create" ? "Proje eklendi." : "Proje güncellendi.");
|
||||
} catch (error) {
|
||||
toast.error(
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: "Proje kaydedilirken beklenmeyen bir hata oluştu.",
|
||||
);
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
@@ -506,14 +514,6 @@ function CoverImageInput({ project }: { project?: ProjectListItem }) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
|
||||
<div>
|
||||
< ImageIcon className="h-6 w-6" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{previewUrl ? (
|
||||
<div className="absolute inset-x-0 bottom-0 bg-background/90 px-3 py-2 text-xs text-muted-foreground backdrop-blur">
|
||||
Görseli değiştirmek için tıkla.
|
||||
@@ -788,8 +788,11 @@ function AIProjectRiskDialog({ projectId }: { projectId?: string }) {
|
||||
throw new Error(data.error || "Bilinmeyen bir hata oluştu.");
|
||||
}
|
||||
setResult(data.text);
|
||||
} catch (err: any) {
|
||||
setResult("Hata: " + err.message);
|
||||
} catch (err) {
|
||||
setResult(
|
||||
"Hata: " +
|
||||
(err instanceof Error ? err.message : "Bilinmeyen bir hata oluştu."),
|
||||
);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user