-
- {config.selectedIds.length} Selected
-
-
- {config.selectedIds.length && config.selectedIds.length > 0 ? (
-
- ) : (
-
- )}
-
-
-
+ {selectedAssets.length &&
+
+
+
+ {config.selectedIds.length} Selected
+
+
+
+
+
+
+
+
+
+
+
+ Delete
+
+
+
-
-
+
+ }
);
diff --git a/src/pages/api/albums/potential-albums-dates.ts b/src/pages/api/albums/potential-albums-dates.ts
index 041cb27..ebbd867 100644
--- a/src/pages/api/albums/potential-albums-dates.ts
+++ b/src/pages/api/albums/potential-albums-dates.ts
@@ -3,52 +3,49 @@ import { db } from "@/config/db";
import { IPotentialAlbumsDatesResponse } from "@/handlers/api/album.handler";
import { getCurrentUser } from "@/handlers/serverUtils/user.utils";
import { parseDate } from "@/helpers/date.helper";
-import { sql } from "drizzle-orm";
+import { albumsAssetsAssets } from "@/schema/albumAssetsAssets.schema";
+import { albums } from "@/schema/albums.schema";
+import { assets } from "@/schema/assets.schema";
+import { exif } from "@/schema/exif.schema";
+import { and, count, desc, eq, gte, isNotNull, isNull, sql } from "drizzle-orm";
import type { NextApiRequest, NextApiResponse } from "next";
+import { number } from "zod";
-const SELECT_ORPHAN_PHOTOS = (ownerId: string) => sql`
-SELECT
- DATE(e."dateTimeOriginal") AS "date",
- COUNT(a."id") AS "asset_count"
-FROM
- "assets" a
-LEFT JOIN
- "albums_assets_assets" aaa ON a."id" = aaa."assetsId"
-LEFT JOIN
- "exif" e ON a."id" = e."assetId"
-WHERE
- aaa."albumsId" IS NULL
- AND a."ownerId" = ${ownerId}
- AND a."isVisible" = true
- AND e."dateTimeOriginal" IS NOT NULL
-GROUP BY
- DATE(e."dateTimeOriginal")
-ORDER BY
- "asset_count" DESC;
-`;
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
try {
- const { sortBy = "date", sortOrder = "desc" } = req.query;
+ const { sortBy = "date", sortOrder = "desc", minAssets = 1 } = req.query as any;
const currentUser = await getCurrentUser(req)
- const data = await db.execute(SELECT_ORPHAN_PHOTOS(currentUser.id)) as any;
- const rows = data.rows as IPotentialAlbumsDatesResponse[];
+ const rows = await db.select({
+ date: sql`DATE(${exif.dateTimeOriginal})`,
+ asset_count: desc(count(assets.id)),
+ }).from(assets)
+ .leftJoin(albumsAssetsAssets, eq(assets.id, albumsAssetsAssets.assetsId))
+ .leftJoin(exif, eq(assets.id, exif.assetId))
+ .where(and (
+ eq(assets.ownerId, currentUser.id),
+ eq(assets.isVisible, true),
+ isNull(albumsAssetsAssets.albumsId),
+ isNotNull(exif.dateTimeOriginal),
+
+ ))
+ .groupBy(sql`DATE(${exif.dateTimeOriginal})`) as IPotentialAlbumsDatesResponse[];
+
+ const filteredRows = rows.filter((row) => Number(row.asset_count) >= Number(minAssets));
if (sortBy === "date") {
- rows.sort((a, b) => {
- const aDate = parseDate(a.date, "yyyy-MM-dd");
- const bDate = parseDate(b.date, "yyyy-MM-dd");
+ filteredRows.sort((a, b) => {
+ const aDate = parseDate(a.date as string, "yyyy-MM-dd");
+ const bDate = parseDate(b.date as string, "yyyy-MM-dd");
return sortOrder === "asc" ? aDate.getTime() - bDate.getTime() : bDate.getTime() - aDate.getTime();
});
} else if (sortBy === "asset_count") {
- rows.sort((a, b) => {
- return sortOrder === "asc" ? a.asset_count - b.asset_count : b.asset_count - a.asset_count;
- });
+ filteredRows.sort((a, b) => sortOrder === "asc" ? a.asset_count - b.asset_count : b.asset_count - a.asset_count);
}
- return res.status(200).json(rows);
+ return res.status(200).json(filteredRows);
} catch (error: any) {
res.status(500).json({
error: error?.message,
diff --git a/src/pages/assets/missing-locations.tsx b/src/pages/assets/missing-locations.tsx
index cbdc167..a395a77 100644
--- a/src/pages/assets/missing-locations.tsx
+++ b/src/pages/assets/missing-locations.tsx
@@ -19,6 +19,7 @@ import FloatingBar from "@/components/shared/FloatingBar";
import { Select, SelectValue, SelectTrigger, SelectContent, SelectItem } from "@/components/ui/select";
import { AlertDialog } from "@/components/ui/alert-dialog";
import AssetOffsetDialog from "@/components/assets/assets-options/AssetOffsetDialog";
+import { Input } from "@/components/ui/input";
export default function MissingLocations() {
const { query, push } = useRouter();
@@ -110,57 +111,58 @@ export default function MissingLocations() {
-