feat: calendar
This commit is contained in:
1 parent
5087492e25
commit
8d739e2aba
14 files changed
+2844
No files matched your search
@@ -0,0 +1,427 @@
|
||||
import { WEBUI_API_BASE_URL } from '$lib/constants';
|
||||
|
||||
export type CalendarModel = {
|
||||
id: string;
|
||||
user_id: string;
|
||||
name: string;
|
||||
color: string | null;
|
||||
is_system: boolean;
|
||||
data: Record<string, any> | null;
|
||||
meta: Record<string, any> | null;
|
||||
access_grants: any[];
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
};
|
||||
|
||||
export type CalendarEventAttendeeModel = {
|
||||
id: string;
|
||||
event_id: string;
|
||||
user_id: string;
|
||||
status: string;
|
||||
meta: Record<string, any> | null;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
};
|
||||
|
||||
export type CalendarEventModel = {
|
||||
id: string;
|
||||
calendar_id: string;
|
||||
user_id: string;
|
||||
title: string;
|
||||
description: string | null;
|
||||
start_at: number;
|
||||
end_at: number | null;
|
||||
all_day: boolean;
|
||||
rrule: string | null;
|
||||
color: string | null;
|
||||
location: string | null;
|
||||
data: Record<string, any> | null;
|
||||
meta: Record<string, any> | null;
|
||||
is_cancelled: boolean;
|
||||
attendees: CalendarEventAttendeeModel[];
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
// Set by expand_recurring_event for recurring instances
|
||||
instance_id?: string;
|
||||
};
|
||||
|
||||
export type CalendarEventForm = {
|
||||
calendar_id: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
start_at: number;
|
||||
end_at?: number;
|
||||
all_day?: boolean;
|
||||
rrule?: string;
|
||||
color?: string;
|
||||
location?: string;
|
||||
data?: Record<string, any>;
|
||||
meta?: Record<string, any>;
|
||||
attendees?: { user_id: string; status?: string }[];
|
||||
};
|
||||
|
||||
export type CalendarForm = {
|
||||
name: string;
|
||||
color?: string;
|
||||
data?: Record<string, any>;
|
||||
meta?: Record<string, any>;
|
||||
access_grants?: { target_type: string; target_id: string; permission: string }[];
|
||||
};
|
||||
|
||||
// ── Calendars ─────────────────────────────────
|
||||
|
||||
export const getCalendars = async (token: string): Promise<CalendarModel[]> => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const createCalendar = async (token: string, form: CalendarForm): Promise<CalendarModel> => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/create`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify(form)
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const updateCalendar = async (
|
||||
token: string,
|
||||
calendarId: string,
|
||||
form: Partial<CalendarForm>
|
||||
): Promise<CalendarModel> => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/${calendarId}/update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify(form)
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const deleteCalendar = async (token: string, calendarId: string): Promise<boolean> => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/${calendarId}/delete`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res?.status ?? false;
|
||||
};
|
||||
|
||||
// ── Events ─────────────────────────────────
|
||||
|
||||
export const getCalendarEvents = async (
|
||||
token: string,
|
||||
start: string,
|
||||
end: string,
|
||||
calendarIds?: string[]
|
||||
): Promise<CalendarEventModel[]> => {
|
||||
let error = null;
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.append('start', start);
|
||||
params.append('end', end);
|
||||
if (calendarIds && calendarIds.length > 0) {
|
||||
params.append('calendar_ids', calendarIds.join(','));
|
||||
}
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/events?${params.toString()}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const createCalendarEvent = async (
|
||||
token: string,
|
||||
form: CalendarEventForm
|
||||
): Promise<CalendarEventModel> => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/events/create`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify(form)
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const getCalendarEventById = async (
|
||||
token: string,
|
||||
eventId: string
|
||||
): Promise<CalendarEventModel> => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/events/${eventId}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const updateCalendarEvent = async (
|
||||
token: string,
|
||||
eventId: string,
|
||||
form: Partial<CalendarEventForm>
|
||||
): Promise<CalendarEventModel> => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/events/${eventId}/update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify(form)
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const deleteCalendarEvent = async (token: string, eventId: string): Promise<boolean> => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/events/${eventId}/delete`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res?.status ?? false;
|
||||
};
|
||||
|
||||
export const rsvpCalendarEvent = async (
|
||||
token: string,
|
||||
eventId: string,
|
||||
status: string
|
||||
): Promise<{ status: boolean; rsvp: string }> => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/events/${eventId}/rsvp`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({ status })
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
export const searchCalendarEvents = async (
|
||||
token: string,
|
||||
query: string | null,
|
||||
skip: number = 0,
|
||||
limit: number = 30
|
||||
): Promise<{ items: CalendarEventModel[]; total: number }> => {
|
||||
let error = null;
|
||||
|
||||
const params = new URLSearchParams();
|
||||
if (query) params.append('query', query);
|
||||
params.append('skip', skip.toString());
|
||||
params.append('limit', limit.toString());
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/events/search?${params.toString()}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
Reference in new issue
Block a user