Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/web/app/(org)/dashboard/Contexts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type SharedContext = {
sharedSpaces: Spaces[] | null;
activeSpace: Spaces | null;
user: typeof users.$inferSelect;
userCapsCount: number | null;
isSubscribed: boolean;
toggleSidebarCollapsed: () => void;
anyNewNotifications: boolean;
Expand Down Expand Up @@ -54,6 +55,7 @@ export function DashboardContexts({
organizationData,
activeOrganization,
spacesData,
userCapsCount,
user,
isSubscribed,
organizationSettings,
Expand All @@ -67,6 +69,7 @@ export function DashboardContexts({
organizationData: SharedContext["organizationData"];
activeOrganization: SharedContext["activeOrganization"];
spacesData: SharedContext["spacesData"];
userCapsCount: SharedContext["userCapsCount"];
user: SharedContext["user"];
isSubscribed: SharedContext["isSubscribed"];
organizationSettings: SharedContext["organizationSettings"];
Expand Down Expand Up @@ -160,6 +163,7 @@ export function DashboardContexts({
organizationData,
activeOrganization,
spacesData,
userCapsCount,
anyNewNotifications,
userPreferences,
organizationSettings,
Expand Down
11 changes: 10 additions & 1 deletion apps/web/app/(org)/dashboard/_components/Navbar/Items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,13 @@ const AdminNavItems = ({ toggleMobileNav }: Props) => {
const pathname = usePathname();
const [open, setOpen] = useState(false);
const [hoveredItem, setHoveredItem] = useState<string | null>(null);
const { user, sidebarCollapsed } = useDashboardContext();
const { user, sidebarCollapsed, userCapsCount } = useDashboardContext();

const manageNavigation = [
{
name: "My Caps",
href: `/dashboard/caps`,
extraText: userCapsCount,
icon: <CapIcon />,
subNav: [],
},
Expand Down Expand Up @@ -346,6 +347,7 @@ const AdminNavItems = ({ toggleMobileNav }: Props) => {
sidebarCollapsed={sidebarCollapsed}
toggleMobileNav={toggleMobileNav}
isPathActive={isPathActive}
extraText={item.extraText}
/>
</div>
))}
Expand Down Expand Up @@ -435,6 +437,7 @@ const NavItem = ({
sidebarCollapsed,
toggleMobileNav,
isPathActive,
extraText,
}: {
name: string;
href: string;
Expand All @@ -446,6 +449,7 @@ const NavItem = ({
sidebarCollapsed: boolean;
toggleMobileNav?: () => void;
isPathActive: (path: string) => boolean;
extraText: number | null | undefined;
}) => {
const iconRef = useRef<CogIconHandle>(null);
return (
Expand Down Expand Up @@ -487,6 +491,11 @@ const NavItem = ({
>
{name}
</p>
{extraText && !sidebarCollapsed && (
<p className="ml-auto text-xs font-medium text-gray-11">
{extraText}
</p>
)}
</Link>
</Tooltip>
);
Expand Down
3 changes: 1 addition & 2 deletions apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ import type { DownloadIconHandle } from "../AnimatedIcons/Download";
import type { ReferIconHandle } from "../AnimatedIcons/Refer";

const Top = () => {
const { activeSpace, anyNewNotifications, activeOrganization } =
useDashboardContext();
const { activeSpace, anyNewNotifications } = useDashboardContext();
const [toggleNotifications, setToggleNotifications] = useState(false);
const bellRef = useRef<HTMLDivElement>(null);
const { theme, setThemeHandler } = useTheme();
Expand Down
8 changes: 7 additions & 1 deletion apps/web/app/(org)/dashboard/caps/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,13 @@ export default async function CapsPage(props: PageProps<"/dashboard/caps">) {
const totalCountResult = await db()
.select({ count: count() })
.from(videos)
.where(eq(videos.ownerId, userId));
.leftJoin(organizations, eq(videos.orgId, organizations.id))
.where(
and(
eq(videos.ownerId, userId),
eq(organizations.id, user.activeOrganizationId),
),
);

const totalCount = totalCountResult[0]?.count || 0;

Expand Down
19 changes: 18 additions & 1 deletion apps/web/app/(org)/dashboard/dashboard-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
spaceMembers,
spaces,
users,
videos,
} from "@cap/database/schema";
import { and, count, eq, inArray, isNull, or, sql } from "drizzle-orm";

Expand Down Expand Up @@ -85,7 +86,7 @@ export async function getDashboardData(user: typeof userSelectProps) {
let anyNewNotifications = false;
let spacesData: Spaces[] = [];
let organizationSettings: OrganizationSettings | null = null;

let userCapsCount = 0;
// Find active organization ID

let activeOrganizationId = organizationIds.find(
Expand Down Expand Up @@ -181,6 +182,20 @@ export async function getDashboardData(user: typeof userSelectProps) {
);
const orgVideoCount = orgVideoCountResult[0]?.value || 0;

const userCapsCountResult = await db()
.select({
value: sql<number>`COUNT(DISTINCT ${videos.id})`,
})
.from(videos)
.where(
and(
eq(videos.orgId, activeOrgInfo.organization.id),
eq(videos.ownerId, user.id),
),
);

userCapsCount = userCapsCountResult[0]?.value || 0;

const allSpacesEntry = {
id: activeOrgInfo.organization.id,
primary: true,
Expand Down Expand Up @@ -279,12 +294,14 @@ export async function getDashboardData(user: typeof userSelectProps) {
spacesData,
anyNewNotifications,
userPreferences,
userCapsCount,
};
} catch (error) {
console.error("Failed to fetch dashboard data", error);
return {
organizationSelect: [],
spacesData: [],
userCapsCount: null,
anyNewNotifications: false,
userPreferences: null,
organizationSettings: null,
Expand Down
4 changes: 4 additions & 0 deletions apps/web/app/(org)/dashboard/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,23 @@ export default async function DashboardLayout({
}

let organizationSelect: Organization[] = [];
let userCapsCount: number | null = null;
let organizationSettings: OrganizationSettings | null = null;
let spacesData: Spaces[] = [];
let anyNewNotifications = false;
let userPreferences: UserPreferences;
try {
const dashboardData = await getDashboardData(user);
organizationSelect = dashboardData.organizationSelect;
userCapsCount = dashboardData.userCapsCount;
organizationSettings = dashboardData.organizationSettings;
userPreferences = dashboardData.userPreferences?.preferences || null;
spacesData = dashboardData.spacesData;
anyNewNotifications = dashboardData.anyNewNotifications;
} catch (error) {
console.error("Failed to load dashboard data", error);
organizationSelect = [];
userCapsCount = null;
organizationSettings = null;
spacesData = [];
anyNewNotifications = false;
Expand Down Expand Up @@ -75,6 +78,7 @@ export default async function DashboardLayout({
<UploadingProvider>
<DashboardContexts
organizationSettings={organizationSettings}
userCapsCount={userCapsCount}
organizationData={organizationSelect}
activeOrganization={activeOrganization || null}
spacesData={spacesData}
Expand Down