Skip to content
35 changes: 35 additions & 0 deletions apps/web/actions/folders/getAllFolders.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"use server";

import { getCurrentUser } from "@cap/database/auth/session";
import { CurrentUser } from "@cap/web-domain";
import { Effect } from "effect";
import { getAllFolders } from "../../lib/folder";
import { runPromise } from "../../lib/server";

export async function getAllFoldersAction(
root:
| { variant: "user" }
| { variant: "space"; spaceId: string }
| { variant: "org"; organizationId: string }
) {
try {
const user = await getCurrentUser();
if (!user || !user.activeOrganizationId) {
return {
success: false as const,
error: "Unauthorized or no active organization",
};
}

const folders = await runPromise(
getAllFolders(root).pipe(Effect.provideService(CurrentUser, user))
);
return { success: true as const, folders };
} catch (error) {
console.error("Error fetching folders:", error);
return {
success: false as const,
error: "Failed to fetch folders",
};
}
}
98 changes: 98 additions & 0 deletions apps/web/actions/folders/move-videos-to-folder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"use server";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Rename file to follow kebab-case convention.

The filename moveVideosToFolder.ts violates the repository's kebab-case convention for TypeScript modules. As per coding guidelines

Rename the file:

git mv apps/web/actions/folders/moveVideosToFolder.ts apps/web/actions/folders/move-videos-to-folder.ts

Update the import in any files that reference this action:

-import { moveVideosToFolderAction } from '@/actions/folders/moveVideosToFolder';
+import { moveVideosToFolderAction } from '@/actions/folders/move-videos-to-folder';
🤖 Prompt for AI Agents
In apps/web/actions/folders/moveVideosToFolder.ts around line 1, the filename
violates the repo's kebab-case convention; rename the file to
apps/web/actions/folders/move-videos-to-folder.ts (e.g. git mv ...) and update
all imports/usages across the codebase to the new path (search for
"moveVideosToFolder" and replace import paths, update any relative paths, and
run TypeScript build/tests to ensure no remaining references).


import { getCurrentUser } from "@cap/database/auth/session";
import { CurrentUser, Video, Folder, Policy } from "@cap/web-domain";
import { SpacesPolicy } from "@cap/web-backend";
import { Effect } from "effect";
import { moveVideosToFolder } from "../../lib/folder";
import { runPromise } from "../../lib/server";
import { revalidatePath } from "next/cache";

interface MoveVideosToFolderParams {
videoIds: string[];
targetFolderId: string | null;
spaceId?: string | null;
}

export async function moveVideosToFolderAction({
videoIds,
targetFolderId,
spaceId,
}: MoveVideosToFolderParams) {
try {
const user = await getCurrentUser();
if (!user || !user.activeOrganizationId) {
return {
success: false as const,
error: "Unauthorized or no active organization",
};
}

const typedVideoIds = videoIds.map((id) => Video.VideoId.make(id));
const typedTargetFolderId = targetFolderId
? Folder.FolderId.make(targetFolderId)
: null;

const root = spaceId
? { variant: "space" as const, spaceId }
: { variant: "org" as const, organizationId: user.activeOrganizationId };

const moveVideosEffect = spaceId
? Effect.gen(function* () {
const spacesPolicy = yield* SpacesPolicy;

return yield* moveVideosToFolder(
typedVideoIds,
typedTargetFolderId,
root
).pipe(Policy.withPolicy(spacesPolicy.isMember(spaceId)));
}).pipe(Effect.provideService(CurrentUser, user))
: moveVideosToFolder(typedVideoIds, typedTargetFolderId, root).pipe(
Effect.provideService(CurrentUser, user)
);

const result = await runPromise(moveVideosEffect);

revalidatePath("/dashboard/caps");

if (spaceId) {
revalidatePath(`/dashboard/spaces/${spaceId}`);
result.originalFolderIds.forEach((folderId) => {
if (folderId) {
revalidatePath(`/dashboard/spaces/${spaceId}/folder/${folderId}`);
}
});
if (result.targetFolderId) {
revalidatePath(
`/dashboard/spaces/${spaceId}/folder/${result.targetFolderId}`
);
}
} else {
result.originalFolderIds.forEach((folderId) => {
if (folderId) {
revalidatePath(`/dashboard/folder/${folderId}`);
}
});
if (result.targetFolderId) {
revalidatePath(`/dashboard/folder/${result.targetFolderId}`);
}
}

return {
success: true as const,
message: `Successfully moved ${result.movedCount} video${
result.movedCount !== 1 ? "s" : ""
} to ${result.targetFolderId ? "folder" : "root"}`,
movedCount: result.movedCount,
originalFolderIds: result.originalFolderIds,
targetFolderId: result.targetFolderId,
videoCountDeltas: result.videoCountDeltas,
};
} catch (error) {
console.error("Error moving videos to folder:", error);
return {
success: false as const,
error: error instanceof Error ? error.message : "Failed to move videos",
};
}
}
Empty file.
Loading
Loading