diff --git a/src/app/(platform)/_components/destination.tsx b/src/app/(platform)/_components/destination.tsx
index 28d3745..613abab 100644
--- a/src/app/(platform)/_components/destination.tsx
+++ b/src/app/(platform)/_components/destination.tsx
@@ -691,6 +691,7 @@ export function DestinationCard(
{String(props.type).charAt(0).toUpperCase() +
String(props.type).slice(1)}
+
{props.tags && props.tags?.length > 0
? props.tags.map((tag) => (
@@ -698,6 +699,9 @@ export function DestinationCard(
))
: null}
+
+ {props.workspace.emoji + " " + props.workspace.name}
+
diff --git a/src/app/(platform)/_components/list.tsx b/src/app/(platform)/_components/list.tsx
index c1e294e..88879c2 100644
--- a/src/app/(platform)/_components/list.tsx
+++ b/src/app/(platform)/_components/list.tsx
@@ -149,6 +149,10 @@ export function ListCard(props: List) {
))
: null}
+
+ {props.workspace.emoji + " " + props.workspace.name}
+
+
@@ -603,6 +607,9 @@ export function ListPage(props: { id: string }) {
))}
) : null}
+
+
+
{data?.size && (
@@ -611,7 +618,7 @@ export function ListPage(props: { id: string }) {
•
- )}
+ )}
{(data?.updatedAt &&
"Updated " +
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index b567f86..c63f2a8 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -10,8 +10,9 @@ import PostHogPageView from "./PostHogPageView";
import { CSPostHogProvider } from "./providers";
export const metadata: Metadata = {
- title: "Regreso | Dashboard",
- description: "Regreso is an app that helps you find your way back.",
+ title: "Regreso | App Dashboard",
+ description:
+ "Regreso is an app that helps you find your way back. Never lose your digital trail again by effortlessly finding your way back to websites, articles, and resources.",
icons: [
{ rel: "icon", url: "/favicon.ico", sizes: "any" },
{ rel: "icon", url: "/favicon.svg", type: "image/svg+xml" },
diff --git a/src/components/sidebar-left.tsx b/src/components/sidebar-left.tsx
index 85a9681..f1c55a0 100644
--- a/src/components/sidebar-left.tsx
+++ b/src/components/sidebar-left.tsx
@@ -139,19 +139,28 @@ export function SidebarLeft({ ...props }: ComponentProps
) {
const [mode, setMode] = useState<"fav" | "rec">("rec");
const [oldMode, setOldMode] = useState<"fav" | "rec">("rec");
- const { data: recentLists = { items: [], count: 0 }, refetch } =
+ const { data: recentLists = { items: [], count: 0 }, refetchLists } =
api.list.getMany.useQuery({
limit: 3,
order: "DESC",
tags: mode === "fav" ? ["favorite maps"] : undefined,
});
+ const {
+ data: recentWorkspaces = { items: [], count: 0 },
+ refetch: refetchWorkspaces,
+ } = api.workspace.getMany.useQuery({
+ limit: 3,
+ order: "DESC",
+ includeLists: true,
+ });
+
useEffect(() => {
if (mode !== oldMode) {
- void refetch();
+ void refetchLists();
setOldMode(mode);
}
- }, [mode, refetch, oldMode, setOldMode]);
+ }, [mode, refetchLists, oldMode, setOldMode]);
return (
@@ -161,7 +170,7 @@ export function SidebarLeft({ ...props }: ComponentProps) {
{
return {
@@ -176,7 +185,31 @@ export function SidebarLeft({ ...props }: ComponentProps) {
/>
-
+ {
+ return {
+ id: w.id,
+ name: w.name,
+ emoji: w.emoji,
+ {
+ return {
+ id: w.id,
+ name: w.name,
+ emoji: w.emoji,
+ pages: w.lists.map((list) => ({
+ name: list.name,
+ url: "/map/" + list.id,
+ emoji: list.emoji ?? "❔",
+ })),
+ };
+ })}
+ />
+
+ ],
+ };
+ })}
+ />
diff --git a/src/server/api/routers/destination.ts b/src/server/api/routers/destination.ts
index 958fad9..2677a2d 100644
--- a/src/server/api/routers/destination.ts
+++ b/src/server/api/routers/destination.ts
@@ -30,6 +30,7 @@ import {
lists,
listTags,
tags,
+ workspaces,
} from "~/server/db/schema";
export const destinationRouter = createTRPCRouter({
@@ -129,9 +130,11 @@ export const destinationRouter = createTRPCRouter({
const dests = await ctx.db
.select({
destination: destinations,
+ workspace: workspaces,
count: sql`count(*) over()`,
})
.from(destinations)
+ .leftJoin(workspaces, eq(destinations.workspaceId, workspaces.id))
.leftJoin(
destinationLists,
listIds.length > 0 || tagNames.length > 0
@@ -191,7 +194,7 @@ export const destinationRouter = createTRPCRouter({
eq(destinations.userId, ctx.user.id),
),
)
- .groupBy(destinations.id)
+ .groupBy(destinations.id, workspaces.id)
.having(
and(
tagNames.length > 0
@@ -212,6 +215,7 @@ export const destinationRouter = createTRPCRouter({
)
.limit(input.limit)
.offset(input.offset);
+
const destTags = await ctx.db
.select()
.from(destinationTags)
@@ -226,7 +230,7 @@ export const destinationRouter = createTRPCRouter({
const returnDestinations = dests.map((dest) => {
const destination = {
id: dest.destination.id,
- workspaceId: dest.destination.workspaceId,
+ workspace: dest.workspace,
userId: dest.destination.userId,
createdAt: dest.destination.createdAt,
updatedAt: dest.destination.updatedAt,
@@ -249,6 +253,7 @@ export const destinationRouter = createTRPCRouter({
};
return destination;
});
+
return {
items: returnDestinations,
count:
@@ -379,6 +384,9 @@ export const destinationRouter = createTRPCRouter({
eq(destinations.id, input.id),
eq(destinations.userId, ctx.user.id),
),
+ with: {
+ workspace: true,
+ },
});
if (!dest) {
throw new TRPCError({
diff --git a/src/server/api/routers/list.ts b/src/server/api/routers/list.ts
index 3b20843..1635aa5 100644
--- a/src/server/api/routers/list.ts
+++ b/src/server/api/routers/list.ts
@@ -20,6 +20,7 @@ import {
lists,
listTags,
tags,
+ workspaces,
} from "~/server/db/schema";
export const listRouter = createTRPCRouter({
@@ -122,6 +123,7 @@ export const listRouter = createTRPCRouter({
),
})
.from(lists)
+
.leftJoin(destinationLists, eq(lists.id, destinationLists.listId))
.leftJoin(
destinations,
@@ -139,6 +141,7 @@ export const listRouter = createTRPCRouter({
latestCreatedAt: sql`${stats.latestCreatedAt}`.as(
"updated_at",
),
+ workspace: workspaces,
})
.from(lists)
.leftJoin(stats, eq(lists.id, stats.listId))
@@ -150,6 +153,7 @@ export const listRouter = createTRPCRouter({
tags,
tagNames.length > 0 ? eq(listTags.tagId, tags.id) : sql`1 = 0`,
)
+ .rightJoin(workspaces, eq(lists.workspaceId, workspaces.id))
.where(
and(
and(
@@ -168,6 +172,7 @@ export const listRouter = createTRPCRouter({
eq(lists.userId, ctx.user.id),
),
)
+
.groupBy(
lists.id,
lists.name,
@@ -176,6 +181,7 @@ export const listRouter = createTRPCRouter({
lists.createdAt,
stats.size,
stats.latestCreatedAt,
+ workspaces.id,
)
.orderBy(
input.order === "ASC"
@@ -209,6 +215,7 @@ export const listRouter = createTRPCRouter({
);
const returnLists: List[] = lsts.map((list) => {
+ delete list.list.workspaceId;
return {
tags: lstTags
.filter((tag) => tag.list_tag.listId == list.list.id)
@@ -236,6 +243,7 @@ export const listRouter = createTRPCRouter({
)?.[0] ?? null)
: null
: null,
+ workspace: list.workspace,
};
});
if (!lsts || lsts.length === 0) {
@@ -244,6 +252,7 @@ export const listRouter = createTRPCRouter({
message: "No lists found",
});
}
+
return {
items: returnLists,
count:
@@ -435,7 +444,6 @@ export const listRouter = createTRPCRouter({
emoji: lists.emoji,
createdAt: lists.createdAt,
userId: lists.userId,
- workspaceId: lists.workspaceId,
count: sql`count(*) over()`,
size: sql`COUNT(${destinationLists}.id)`,
updatedAt: sql`(
@@ -447,8 +455,9 @@ export const listRouter = createTRPCRouter({
})
.from(lists)
.leftJoin(destinationLists, eq(lists.id, destinationLists.listId))
+ .leftJoin(workspaces, eq(lists.workspaceId, workspaces.id))
.where(and(eq(lists.id, input.id), eq(lists.userId, ctx.user.id)))
- .groupBy(lists.id)
+ .groupBy(lists.id, workspaces.id)
.limit(1);
if (!lstData || lstData.length === 0 || !lstData[0]) {
diff --git a/src/server/models.ts b/src/server/models.ts
index 3a7c6a0..f12e30d 100644
--- a/src/server/models.ts
+++ b/src/server/models.ts
@@ -39,7 +39,7 @@ export interface Destination {
tags?: { id: number; text: string }[];
updatedAt: Date | null;
lists?: List[];
- workspaceId: number;
+ workspace: Workspace;
}
export interface List {
@@ -52,7 +52,7 @@ export interface List {
size?: number;
updatedAt?: Date | null;
tags?: { id: number; text: string }[];
- workspaceId: number;
+ workspace: Workspace;
}
export interface Workspace {
@@ -64,6 +64,7 @@ export interface Workspace {
createdAt: Date;
destinationCount?: number;
listCount?: number;
+ lists?: List[];
}
export interface Tag {
@@ -75,7 +76,7 @@ export interface Tag {
userId: number;
destinationCount?: number;
listCount?: number;
- workspaceId: number | null;
+ workspace: Workspace | null;
createdAt: Date;
updatedAt: Date | null;
}
@@ -175,6 +176,16 @@ export const tagFormSchema = z.object({
workspaceId: z.number(),
});
+export const workspaceSchema = z.object({
+ id: z.number(),
+ userId: z.number(),
+ createdAt: z.date(),
+ name: z.string(),
+ description: z.string().nullable(),
+ emoji: z.string().nullable(),
+ lists: z.array(z.any()).optional(),
+});
+
export const destinationSchema = z.object({
id: z.number(),
userId: z.number(),
@@ -186,7 +197,7 @@ export const destinationSchema = z.object({
location: z.string().nullable(),
body: z.string().nullable(),
attachments: z.array(z.any()).optional(),
- workspaceId: z.number(),
+ workspace: workspaceSchema,
});
export const listSchema = z.object({
@@ -198,19 +209,10 @@ export const listSchema = z.object({
size: z.number().optional(),
name: z.string(),
emoji: z.string().nullable(),
- workspaceId: z.number(),
+ workspace: workspaceSchema,
description: z.string().nullable(),
});
-export const workspaceSchema = z.object({
- id: z.number(),
- userId: z.number(),
- createdAt: z.date(),
- name: z.string(),
- description: z.string().nullable(),
- emoji: z.string().nullable(),
-});
-
export const tagSchema = z.object({
id: z.number(),
userId: z.number(),
@@ -280,6 +282,7 @@ export const workspaceSearchSchema = z.object({
order: z.enum(["ASC", "DESC"]).optional(),
limit: z.number().max(30).optional().default(5),
offset: z.number().optional().default(0),
+ includeLists: z.boolean().optional().default(false),
});
export const tagSearchSchema = z.object({
diff --git a/src/server/user.ts b/src/server/user.ts
index 594afca..ef2a96b 100644
--- a/src/server/user.ts
+++ b/src/server/user.ts
@@ -66,6 +66,7 @@ export async function createUser(
.values({
userId: userRow[0]!.id,
name: "Default Workspace",
+ emoji: "🧰",
description:
"This is your first workspace. Do something awesome with it!",
})