Files
calendar/apps/web/components/booking/SkeletonLoader.tsx
T
Rodrigo EhlersGitHubeunjae@cal.com <hey@eunjae.dev>Eunjae LeeDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
89230474a5 feat: bookings page redesign v3 with calendar view (#24664)
* bookings page redesign work in progress

fix: duplicate translation key

chore: use newly supported separator type

remove outdated BookingDetailsSheet

remove dropdown and related code

revert unncessary changes

* fix wrong rebase

* fix type error

* refactor: separate bookings columns into filter and display columns (#24959)

* refactor: separate bookings columns into filter and display columns

- Extract filter-only columns into shared filterColumns.ts
- Extract list display columns into listColumns.tsx
- Create BookingsListContainer for list view with both column sets
- Create BookingsCalendarContainer for calendar view with filter columns only
- Refactor bookings-view.tsx to use dynamic imports for containers
- Remove column/table creation logic from bookings-view.tsx

This ensures calendar view doesn't import list-specific UI components (AvatarGroup, Badge, etc.)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: return null instead of false for separator rows in filter accessors

The filter accessor functions were returning false for separator rows instead of null,
which would pollute the multi-select filters with bogus 'false' values.

This fix ensures that separator rows return null so they are properly excluded from filters.

Addresses cubic AI reviewer feedback on PR #24959

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up filter column visibility

* feat: integrate booking calendar view with re-designed list (#24973)

* add toggle button

* remove the dateRange filter when switching from calendar to list view

* move "view" to the action dropdown

* add close button the details sheet

* move close button

* fix more button behavior

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix type error

* update the test case

* fix e2e util

* fix actions dropdown

* revert e2e tests

* fix type error on BookingActionsDropdown.tsx

* fix: include today's bookings in flatData for past status

Previously, flatData excluded groupedBookings.today, which caused
past bookings that happened today to not show up when status === 'past'.
This fix includes today's bookings in flatData for all statuses.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* improve attendee cell

* fix e2e tests

* change max

* fix e2e

* add reschedule requested message

* fix e2e

* update e2e

* remove flaky checks

---------

Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-13 16:20:48 +00:00

84 lines
2.5 KiB
TypeScript

import React from "react";
import classNames from "@calcom/ui/classNames";
import { SkeletonAvatar, SkeletonText } from "@calcom/ui/components/skeleton";
function SkeletonLoader() {
return (
<div className="animate-pulse">
{/* Table rows with separator at the beginning */}
<div className="divide-subtle divide-y">
{/* Month separator skeleton */}
<div className="bg-muted rounded-t py-2">
<SkeletonItem isHeader={true} />
</div>
<div className="bg-muted">
<SkeletonText className="ml-2 mt-3 h-4 w-28 rounded" />
</div>
<SkeletonItem />
<SkeletonItem />
<SkeletonItem />
<SkeletonItem />
<SkeletonItem />
</div>
</div>
);
}
export default SkeletonLoader;
function SkeletonItem({ isHeader = false }: { isHeader?: boolean }) {
return (
<div
className={classNames(
"grid grid-cols-[132px_130px_185px_150px_140px_280px] gap-6 px-2",
isHeader ? "py-2" : "py-2.5"
)}>
{/* Date column - 140px */}
<div className="flex items-center">
<SkeletonText className={classNames("h-4 rounded", isHeader ? "w-12" : "w-20")} />
</div>
{/* Time column - 140px */}
<div className="flex items-center">
<SkeletonText className={classNames("h-4 rounded", isHeader ? "w-12" : "w-28")} />
</div>
{/* Event column - 200px */}
<div className="flex items-center">
<SkeletonText className={classNames("h-4 rounded", isHeader ? "w-16" : "w-full")} />
</div>
{/* Who column - 160px, Avatar group */}
<div className="flex items-center -space-x-1">
{isHeader && <SkeletonText className="h-4 w-20 rounded" />}
{!isHeader && (
<>
<SkeletonAvatar className="h-6 w-6 rounded-full" />
<SkeletonAvatar className="h-6 w-6 rounded-full" />
<SkeletonAvatar className="h-6 w-6 rounded-full" />
</>
)}
</div>
{/* Team column - 140px */}
<div className="flex items-center">
<SkeletonText className="h-4 w-20 rounded-md" />
</div>
{/* Actions column - 280px */}
<div className="mr-2 flex items-center justify-end gap-2">
{isHeader && <SkeletonText className="h-4 w-16 rounded-md" />}
{!isHeader && (
<>
<SkeletonText className="h-4 w-16 rounded-md" />
<SkeletonText className="h-4 w-20 rounded-md" />
<SkeletonText className="h-4 w-8 rounded-md" />
</>
)}
</div>
</div>
);
}