feat(calendar): replace CSS-transform zoom with GSAP flying-rect animation and scope data to year

- Add CalendarDateRange input to GraphQL schema; server resolver now accepts from/to params
- Frontend query sends year-scoped date range variables reactively
- Rewrite zoom-in/zoom-out animations using GSAP flying-rect overlay (650ms vs 2400ms)
- Add flying-rect element to CrmCalendarPanel with proper CSS
- Remove old calendarSceneTransformStyle CSS-transition approach
- Add calendarKillTweens cleanup in onBeforeUnmount

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ruslan Bakiev
2026-02-24 11:41:35 +07:00
parent 638652b4d8
commit 227030b9ae
6 changed files with 217 additions and 181 deletions

View File

@@ -675,10 +675,10 @@ async function getContactInboxes(auth: AuthContext | null) {
}));
}
async function getCalendar(auth: AuthContext | null) {
async function getCalendar(auth: AuthContext | null, dateRange?: { from?: string; to?: string }) {
const ctx = requireAuth(auth);
const from = new Date(Date.now() - 1000 * 60 * 60 * 24 * 30);
const to = new Date(Date.now() + 1000 * 60 * 60 * 24 * 60);
const from = dateRange?.from ? new Date(dateRange.from) : new Date(Date.now() - 1000 * 60 * 60 * 24 * 30);
const to = dateRange?.to ? new Date(dateRange.to) : new Date(Date.now() + 1000 * 60 * 60 * 24 * 60);
const calendarRaw = await prisma.calendarEvent.findMany({
where: { teamId: ctx.teamId, startsAt: { gte: from, lte: to } },
@@ -1842,7 +1842,7 @@ export const crmGraphqlSchema = buildSchema(`
contacts: [Contact!]!
communications: [CommItem!]!
contactInboxes: [ContactInbox!]!
calendar: [CalendarEvent!]!
calendar(dateRange: CalendarDateRange): [CalendarEvent!]!
deals: [Deal!]!
feed: [FeedCard!]!
pins: [CommPin!]!
@@ -1886,6 +1886,11 @@ export const crmGraphqlSchema = buildSchema(`
pinned: Boolean!
}
input CalendarDateRange {
from: String
to: String
}
input CreateCalendarEventInput {
title: String!
start: String!
@@ -2113,7 +2118,7 @@ export const crmGraphqlRoot = {
contacts: async (_args: unknown, context: GraphQLContext) => getContacts(context.auth),
communications: async (_args: unknown, context: GraphQLContext) => getCommunications(context.auth),
contactInboxes: async (_args: unknown, context: GraphQLContext) => getContactInboxes(context.auth),
calendar: async (_args: unknown, context: GraphQLContext) => getCalendar(context.auth),
calendar: async (args: { dateRange?: { from?: string; to?: string } }, context: GraphQLContext) => getCalendar(context.auth, args.dateRange ?? undefined),
deals: async (_args: unknown, context: GraphQLContext) => getDeals(context.auth),
feed: async (_args: unknown, context: GraphQLContext) => getFeed(context.auth),
pins: async (_args: unknown, context: GraphQLContext) => getPins(context.auth),