@deallony/shared 1.2.82 → 1.2.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/constants/events/EventCustomization.d.ts +18 -0
- package/dist/cjs/constants/events/EventCustomization.js +21 -1
- package/dist/cjs/constants/events/EventTemplate.js +3 -3
- package/dist/cjs/constants/events/EventType.d.ts +21 -90
- package/dist/cjs/constants/events/EventType.js +15 -8
- package/dist/cjs/constants/events/EventWeddingReligion.d.ts +10 -5
- package/dist/cjs/constants/events/EventWeddingReligion.js +12 -27
- package/dist/cjs/constants/routes/app.d.ts +14 -0
- package/dist/cjs/constants/routes/app.js +4 -0
- package/dist/cjs/schema/communication/ai-conversation.schema.d.ts +2 -0
- package/dist/cjs/schema/events/Event.schema.d.ts +38 -0
- package/dist/cjs/schema/events/Event.schema.js +27 -0
- package/dist/cjs/types/ad/Ad.d.ts +2 -0
- package/dist/cjs/types/communication/Notification.d.ts +4 -0
- package/dist/cjs/types/communication/Notification.js +6 -0
- package/dist/cjs/types/events/Event.d.ts +4 -0
- package/dist/cjs/types/events/EventCustomization.d.ts +11 -0
- package/dist/cjs/types/events/EventDay.d.ts +89 -0
- package/dist/cjs/types/events/EventDay.js +2 -0
- package/dist/cjs/types/events/EventInvited.d.ts +25 -0
- package/dist/cjs/types/events/EventInvited.js +2 -0
- package/dist/cjs/types/events/EventRsvp.d.ts +12 -1
- package/dist/cjs/types/events/index.d.ts +2 -0
- package/dist/cjs/types/events/index.js +2 -0
- package/dist/cjs/types/index.d.ts +2 -0
- package/dist/cjs/types/index.js +4 -2
- package/dist/cjs/utils/adSeoTitle.d.ts +35 -0
- package/dist/cjs/utils/adSeoTitle.js +26 -0
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.js +1 -0
- package/dist/esm/constants/events/EventCustomization.js +20 -0
- package/dist/esm/constants/events/EventTemplate.js +3 -3
- package/dist/esm/constants/events/EventType.js +14 -7
- package/dist/esm/constants/events/EventWeddingReligion.js +11 -26
- package/dist/esm/constants/routes/app.js +4 -0
- package/dist/esm/schema/events/Event.schema.js +28 -1
- package/dist/esm/types/communication/Notification.js +6 -0
- package/dist/esm/types/events/EventDay.js +1 -0
- package/dist/esm/types/events/EventInvited.js +1 -0
- package/dist/esm/types/events/index.js +2 -0
- package/dist/esm/types/index.js +2 -0
- package/dist/esm/utils/adSeoTitle.js +23 -0
- package/dist/esm/utils/index.js +1 -0
- package/package.json +1 -1
|
@@ -17,6 +17,15 @@ const customizationText = zod_1.z
|
|
|
17
17
|
.transform((v) => (v.length ? v : null))
|
|
18
18
|
.nullable()
|
|
19
19
|
.optional();
|
|
20
|
+
/** Owner's own wording for the children / food line on the invitation; empty keeps the default */
|
|
21
|
+
const attendanceText = zod_1.z
|
|
22
|
+
.string()
|
|
23
|
+
.trim()
|
|
24
|
+
.max(events_1.EVENT_ATTENDANCE_TEXT_MAX)
|
|
25
|
+
.refine((v) => !(0, EventTextPolicy_1.hasBlockedReligiousText)(v), { message: EventTextPolicy_1.BLOCKED_RELIGIOUS_TEXT_MESSAGE.ar })
|
|
26
|
+
.transform((v) => (v.length ? v : null))
|
|
27
|
+
.nullable()
|
|
28
|
+
.optional();
|
|
20
29
|
exports.eventCustomizationSchema = zod_1.z.object({
|
|
21
30
|
palette: zod_1.z.enum(events_1.EventCustomizationPaletteValues).nullable().optional(),
|
|
22
31
|
font: zod_1.z.enum(events_1.EventCustomizationFontValues).nullable().optional(),
|
|
@@ -26,9 +35,23 @@ exports.eventCustomizationSchema = zod_1.z.object({
|
|
|
26
35
|
.optional(),
|
|
27
36
|
welcome_message: customizationText,
|
|
28
37
|
rsvp_message: customizationText,
|
|
38
|
+
children_message: attendanceText,
|
|
39
|
+
food_message: attendanceText,
|
|
29
40
|
music: zod_1.z.enum(events_1.EventCustomizationTrackValues).nullable().optional(),
|
|
30
41
|
opening: zod_1.z.enum(events_1.EventCustomizationOpeningValues).nullable().optional(),
|
|
31
42
|
auto_scroll: zod_1.z.boolean().nullable().optional(),
|
|
43
|
+
cover_video: zod_1.z
|
|
44
|
+
.record(zod_1.z.string(), zod_1.z.any())
|
|
45
|
+
.refine((v) => typeof v.url === "string" && v.url.length > 0, { message: "Video URL is missing" })
|
|
46
|
+
.refine((v) => !(Number(v.size) > events_1.EVENT_COVER_VIDEO_MAX_BYTES), {
|
|
47
|
+
message: "حجم الفيديو أكبر من 100 ميغابايت",
|
|
48
|
+
})
|
|
49
|
+
.refine((v) => !(Number(v.durationSeconds) > events_1.EVENT_COVER_VIDEO_MAX_SECONDS + 1), {
|
|
50
|
+
message: "الفيديو أطول من 60 ثانية",
|
|
51
|
+
})
|
|
52
|
+
.nullable()
|
|
53
|
+
.optional(),
|
|
54
|
+
cover_video_muted: zod_1.z.boolean().nullable().optional(),
|
|
32
55
|
});
|
|
33
56
|
exports.eventDressCodeSchema = zod_1.z.object({
|
|
34
57
|
style: zod_1.z.enum(events_1.EventDressCodeStyleValues).nullable().optional(),
|
|
@@ -77,6 +100,10 @@ exports.eventBaseSchema = zod_1.z.object({
|
|
|
77
100
|
invitation_scan_type: zod_1.z.enum(events_1.EventInvitationScanTypeValues).optional(),
|
|
78
101
|
customization: exports.eventCustomizationSchema.nullable().optional(),
|
|
79
102
|
dress_code: exports.eventDressCodeSchema.nullable().optional(),
|
|
103
|
+
/** Children may come; null for events created before it was asked */
|
|
104
|
+
children_allowed: zod_1.z.boolean().nullable().optional(),
|
|
105
|
+
/** Food is served; null for events created before it was asked */
|
|
106
|
+
food_included: zod_1.z.boolean().nullable().optional(),
|
|
80
107
|
visibility: zod_1.z.enum(events_1.EventVisibilityValues).optional(),
|
|
81
108
|
/** «من أنت في هذه المناسبة؟»: a slot key of the type, "company" or "other" */
|
|
82
109
|
creator_role: zod_1.z.string().trim().max(40).nullable().optional(),
|
|
@@ -27,6 +27,8 @@ export type IAd = {
|
|
|
27
27
|
user_id?: number;
|
|
28
28
|
status_id?: number;
|
|
29
29
|
title?: string;
|
|
30
|
+
/** Auto-generated title saved by the backend on add/update (UTILS.buildAdSeoTitle) */
|
|
31
|
+
seo_title?: string | null;
|
|
30
32
|
description?: string | null;
|
|
31
33
|
category_id?: number | null;
|
|
32
34
|
price?: number | null;
|
|
@@ -23,6 +23,10 @@ export declare enum NotificationTypeEnum {
|
|
|
23
23
|
EVENT_HOST_JOINED = "event_host_joined",
|
|
24
24
|
/** The user no longer has access to an event */
|
|
25
25
|
EVENT_HOST_REMOVED = "event_host_removed",
|
|
26
|
+
/** The user is on an event's guest list («دعواتي») */
|
|
27
|
+
EVENT_INVITED = "event_invited",
|
|
28
|
+
/** A guest's invitation is tomorrow or today («دعواتي») */
|
|
29
|
+
EVENT_REMINDER = "event_reminder",
|
|
26
30
|
/** New ads match one of the user's saved searches */
|
|
27
31
|
SAVED_SEARCH = "saved_search"
|
|
28
32
|
}
|
|
@@ -26,6 +26,10 @@ var NotificationTypeEnum;
|
|
|
26
26
|
NotificationTypeEnum["EVENT_HOST_JOINED"] = "event_host_joined";
|
|
27
27
|
/** The user no longer has access to an event */
|
|
28
28
|
NotificationTypeEnum["EVENT_HOST_REMOVED"] = "event_host_removed";
|
|
29
|
+
/** The user is on an event's guest list («دعواتي») */
|
|
30
|
+
NotificationTypeEnum["EVENT_INVITED"] = "event_invited";
|
|
31
|
+
/** A guest's invitation is tomorrow or today («دعواتي») */
|
|
32
|
+
NotificationTypeEnum["EVENT_REMINDER"] = "event_reminder";
|
|
29
33
|
/** New ads match one of the user's saved searches */
|
|
30
34
|
NotificationTypeEnum["SAVED_SEARCH"] = "saved_search";
|
|
31
35
|
})(NotificationTypeEnum || (exports.NotificationTypeEnum = NotificationTypeEnum = {}));
|
|
@@ -53,5 +57,7 @@ exports.NOTIFICATION_CATEGORY = {
|
|
|
53
57
|
[NotificationTypeEnum.EVENT_HOST_ADDED]: NotificationCategoryEnum.EVENTS,
|
|
54
58
|
[NotificationTypeEnum.EVENT_HOST_JOINED]: NotificationCategoryEnum.EVENTS,
|
|
55
59
|
[NotificationTypeEnum.EVENT_HOST_REMOVED]: NotificationCategoryEnum.EVENTS,
|
|
60
|
+
[NotificationTypeEnum.EVENT_INVITED]: NotificationCategoryEnum.EVENTS,
|
|
61
|
+
[NotificationTypeEnum.EVENT_REMINDER]: NotificationCategoryEnum.EVENTS,
|
|
56
62
|
[NotificationTypeEnum.SAVED_SEARCH]: NotificationCategoryEnum.SAVED_SEARCHES,
|
|
57
63
|
};
|
|
@@ -41,6 +41,10 @@ export type IEvent = {
|
|
|
41
41
|
location_label?: string | null;
|
|
42
42
|
/** Expected number of guests; null for events created before it was asked */
|
|
43
43
|
expected_guests?: number | null;
|
|
44
|
+
/** Children may come; null for events created before it was asked */
|
|
45
|
+
children_allowed?: boolean | null;
|
|
46
|
+
/** Food is served; null for events created before it was asked */
|
|
47
|
+
food_included?: boolean | null;
|
|
44
48
|
user_id?: number | null;
|
|
45
49
|
user?: IUser | null;
|
|
46
50
|
payment_id?: number | null;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IFile } from "../media";
|
|
1
2
|
import type { EventCustomizationSectionKey } from "../../constants/events/EventCustomization";
|
|
2
3
|
/** Owner choices for the invitation page; anything left empty keeps the template's own look */
|
|
3
4
|
export type IEventCustomization = {
|
|
@@ -11,10 +12,20 @@ export type IEventCustomization = {
|
|
|
11
12
|
welcome_message?: string | null;
|
|
12
13
|
/** Replaces the template's RSVP invitation line */
|
|
13
14
|
rsvp_message?: string | null;
|
|
15
|
+
/** Replaces «جنة الأطفال منازلهم» when children are not allowed */
|
|
16
|
+
children_message?: string | null;
|
|
17
|
+
/** Replaces «عشاكم بيحلا معنا» when food is included */
|
|
18
|
+
food_message?: string | null;
|
|
14
19
|
/** EventCustomizationTracks value */
|
|
15
20
|
music?: string | null;
|
|
16
21
|
/** EventCustomizationOpening value: how the invitation opens; empty keeps the template's own */
|
|
17
22
|
opening?: string | null;
|
|
18
23
|
/** False stops the page scrolling by itself; empty means on */
|
|
19
24
|
auto_scroll?: boolean | null;
|
|
25
|
+
/** Video shown in its own section after the cover (uploaded through the assets service) */
|
|
26
|
+
cover_video?: (IFile & {
|
|
27
|
+
durationSeconds?: number | null;
|
|
28
|
+
}) | null;
|
|
29
|
+
/** True plays the video without sound (the music then keeps playing) */
|
|
30
|
+
cover_video_muted?: boolean | null;
|
|
20
31
|
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { IEventOccasion } from './EventOccasion';
|
|
2
|
+
import type { IEventWedding } from './EventWedding';
|
|
3
|
+
/**
|
|
4
|
+
* «يوم المناسبة»: the door tools of an event.
|
|
5
|
+
* ready: nobody of the invitation came in yet; partial: some came in; full: everyone came in;
|
|
6
|
+
* other_event: a real invitation for another event; not_found: no such invitation.
|
|
7
|
+
*/
|
|
8
|
+
export type EventDayLookupStatus = 'ready' | 'partial' | 'full' | 'other_event' | 'not_found';
|
|
9
|
+
/** A guest as the door sees them */
|
|
10
|
+
export type IEventDayGuest = {
|
|
11
|
+
id: number;
|
|
12
|
+
full_name: string;
|
|
13
|
+
phone: string | null;
|
|
14
|
+
/** People on the invitation (at least 1) */
|
|
15
|
+
guest_count: number;
|
|
16
|
+
/** People of the invitation who came in so far */
|
|
17
|
+
arrived_count: number;
|
|
18
|
+
remaining: number;
|
|
19
|
+
attendance_status: 'attending' | 'not_attending' | 'maybe';
|
|
20
|
+
responded_at: string | Date | null;
|
|
21
|
+
/** First and latest time someone of the invitation came in */
|
|
22
|
+
arrived_at: string | Date | null;
|
|
23
|
+
last_arrived_at: string | Date | null;
|
|
24
|
+
/** Added at the door without an invitation */
|
|
25
|
+
walk_in: boolean;
|
|
26
|
+
checked_in_by: number | null;
|
|
27
|
+
checked_in_by_name: string | null;
|
|
28
|
+
};
|
|
29
|
+
/** Another event's basics, when the door scans an invitation that isn't for this event */
|
|
30
|
+
export type IEventDayOtherEvent = {
|
|
31
|
+
id: number;
|
|
32
|
+
event_type: string | null;
|
|
33
|
+
start_date: string | Date | null;
|
|
34
|
+
wedding: IEventWedding | null;
|
|
35
|
+
occasion: IEventOccasion | null;
|
|
36
|
+
venue: {
|
|
37
|
+
id: number;
|
|
38
|
+
name: string;
|
|
39
|
+
} | null;
|
|
40
|
+
};
|
|
41
|
+
export type IEventDayLookup = {
|
|
42
|
+
status: EventDayLookupStatus;
|
|
43
|
+
guest?: IEventDayGuest;
|
|
44
|
+
other_event?: IEventDayOtherEvent | null;
|
|
45
|
+
/** checkIn only: false when nobody more could come in (the invitation was already full) */
|
|
46
|
+
checked_in?: boolean;
|
|
47
|
+
};
|
|
48
|
+
export type IEventDayScanner = {
|
|
49
|
+
user_id: number;
|
|
50
|
+
name: string | null;
|
|
51
|
+
invites: number;
|
|
52
|
+
people: number;
|
|
53
|
+
};
|
|
54
|
+
export type IEventDaySummary = {
|
|
55
|
+
/** Invitations sent out (guests added at the door not counted) */
|
|
56
|
+
invites: number;
|
|
57
|
+
/** People expected: everyone on the invitations except those who said they won't come */
|
|
58
|
+
expected_people: number;
|
|
59
|
+
/** People who came in, guests added at the door included */
|
|
60
|
+
arrived_people: number;
|
|
61
|
+
invites_full: number;
|
|
62
|
+
invites_partial: number;
|
|
63
|
+
not_arrived: number;
|
|
64
|
+
declined: number;
|
|
65
|
+
walk_ins: number;
|
|
66
|
+
walk_in_people: number;
|
|
67
|
+
recent: IEventDayGuest[];
|
|
68
|
+
scanners: IEventDayScanner[];
|
|
69
|
+
};
|
|
70
|
+
/** An event of today the user can let guests in for */
|
|
71
|
+
export type IEventDayToday = {
|
|
72
|
+
id: number;
|
|
73
|
+
event_type: string | null;
|
|
74
|
+
start_date: string | Date | null;
|
|
75
|
+
end_date: string | Date | null;
|
|
76
|
+
is_published: boolean;
|
|
77
|
+
invitation_scan_type: 'none' | 'qrcode' | 'barcode';
|
|
78
|
+
wedding: IEventWedding | null;
|
|
79
|
+
occasion: IEventOccasion | null;
|
|
80
|
+
venue: {
|
|
81
|
+
id: number;
|
|
82
|
+
name: string;
|
|
83
|
+
} | null;
|
|
84
|
+
my_role: 'owner' | 'organiser' | 'guests' | null;
|
|
85
|
+
/** Seen because it is at the user's company's venue */
|
|
86
|
+
via_company: boolean;
|
|
87
|
+
expected_people: number;
|
|
88
|
+
arrived_people: number;
|
|
89
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { IEvent } from './Event';
|
|
2
|
+
import type { IEventRsvp } from './EventRsvp';
|
|
3
|
+
/** The signed-in guest's own row on an event's guest list (never other guests) */
|
|
4
|
+
export type IInvitedRsvp = Pick<IEventRsvp, 'id' | 'event_id' | 'attendance_status' | 'guest_count' | 'seats_fixed' | 'message' | 'responded_at' | 'arrived_at' | 'arrived_count'> & {
|
|
5
|
+
full_name: string;
|
|
6
|
+
/** Their personal invitation link token: /invite/<token> on the event site */
|
|
7
|
+
invite_token: string | null;
|
|
8
|
+
/** When this row was matched to the account (by number or by opening the link) */
|
|
9
|
+
linked_at: string | Date | null;
|
|
10
|
+
};
|
|
11
|
+
/** «دعواتي»: an event the user was invited to, as a guest sees it */
|
|
12
|
+
export type IInvitedEvent = {
|
|
13
|
+
/** The public view of the event: no phones, guests, payment or manage links */
|
|
14
|
+
event: IEvent;
|
|
15
|
+
rsvp: IInvitedRsvp;
|
|
16
|
+
/** Who invited them (owner's name), when known */
|
|
17
|
+
host_name: string | null;
|
|
18
|
+
/** Full personal invitation URL on the event site */
|
|
19
|
+
invite_url: string | null;
|
|
20
|
+
};
|
|
21
|
+
export type IInvitedEventsResponse = {
|
|
22
|
+
values: IInvitedEvent[];
|
|
23
|
+
/** Matched since the user last opened «دعواتي» */
|
|
24
|
+
new_count: number;
|
|
25
|
+
};
|
|
@@ -4,13 +4,24 @@ export type IEventRsvp = {
|
|
|
4
4
|
event_id: number;
|
|
5
5
|
first_name: string;
|
|
6
6
|
last_name: string | null;
|
|
7
|
-
|
|
7
|
+
/** null when the host added the guest by name only */
|
|
8
|
+
phone: string | null;
|
|
8
9
|
attendance_status: 'attending' | 'not_attending' | 'maybe';
|
|
9
10
|
guest_count: number;
|
|
11
|
+
/** The host fixed the seats: the guest's personal invitation can't change guest_count */
|
|
12
|
+
seats_fixed?: boolean;
|
|
10
13
|
message: string | null;
|
|
11
14
|
/** Extra answers with the reply, e.g. { gender_guess: 'boy' } for a gender reveal */
|
|
12
15
|
answers?: Record<string, any> | null;
|
|
13
16
|
responded_at: string | Date | null;
|
|
17
|
+
/** Day of event: first time someone of the invitation came in, and how many came in */
|
|
18
|
+
arrived_at?: string | Date | null;
|
|
19
|
+
arrived_count?: number;
|
|
20
|
+
last_arrived_at?: string | Date | null;
|
|
21
|
+
/** The user who last let them in */
|
|
22
|
+
checked_in_by?: number | null;
|
|
23
|
+
/** Added at the door without an invitation */
|
|
24
|
+
walk_in?: boolean;
|
|
14
25
|
created_at?: string | Date;
|
|
15
26
|
updated_at?: string | Date;
|
|
16
27
|
event?: IEvent;
|
|
@@ -23,3 +23,5 @@ __exportStar(require("./EventOccasion"), exports);
|
|
|
23
23
|
__exportStar(require("./EventCustomization"), exports);
|
|
24
24
|
__exportStar(require("./EventDressCode"), exports);
|
|
25
25
|
__exportStar(require("./EventHost"), exports);
|
|
26
|
+
__exportStar(require("./EventDay"), exports);
|
|
27
|
+
__exportStar(require("./EventInvited"), exports);
|
|
@@ -46,6 +46,8 @@ export * as EventBirthday from './events/EventBirthday';
|
|
|
46
46
|
export * as EventOccasion from './events/EventOccasion';
|
|
47
47
|
export * as EventVenue from './events/EventVenue';
|
|
48
48
|
export * as EventHost from './events/EventHost';
|
|
49
|
+
export * as EventDay from './events/EventDay';
|
|
50
|
+
export * as EventInvited from './events/EventInvited';
|
|
49
51
|
export * as User from "./user/User";
|
|
50
52
|
export * as Role from "./user/Role";
|
|
51
53
|
export * as Permission from "./user/Permission";
|
package/dist/cjs/types/index.js
CHANGED
|
@@ -36,8 +36,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
};
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.
|
|
40
|
-
exports.Payment = exports.Analysis = exports.GeminiApiKey = exports.Google = exports.Kyc = exports.SocialMediaProfile = exports.SocialMediaPlatform = exports.Image = exports.Media = exports.File = exports.Notification = exports.NotificationToken = exports.MessageTemplate = exports.Device = exports.Chat = exports.AppStartScreen = exports.MetaData = exports.Company = exports.PotentialUser = exports.Loyalty = exports.SavedSearch = exports.Favorite = exports.Wallet = exports.Permission = void 0;
|
|
39
|
+
exports.EventInvited = exports.EventDay = exports.EventHost = exports.EventVenue = exports.EventOccasion = exports.EventBirthday = exports.EventWedding = exports.EventTimeline = exports.EventRsvp = exports.Event = exports.District = exports.City = exports.AdminBoundary = exports.WorkType = exports.UsedProductCondition = exports.UsedProductAge = exports.Unit = exports.Transmission = exports.RegionalSpec = exports.PublisherType = exports.PropertyStatus = exports.PriceType = exports.OfferType = exports.LicenseType = exports.FuelType = exports.Feature = exports.Facility = exports.Currency = exports.Color = exports.CategoryWorkType = exports.Category = exports.CarBody = exports.UsedProduct = exports.Service = exports.PropertySubType = exports.Property = exports.MotorTrim = exports.Motor = exports.AdPromotion = exports.Addresses = exports.AdDailyViews = exports.AdLocation = exports.Ad = exports.FilterParams = exports.ModuleFetchEndpoints = exports.Config = exports.AccessType = exports.Status = exports.Response = exports.LocalizedName = void 0;
|
|
40
|
+
exports.Payment = exports.Analysis = exports.GeminiApiKey = exports.Google = exports.Kyc = exports.SocialMediaProfile = exports.SocialMediaPlatform = exports.Image = exports.Media = exports.File = exports.Notification = exports.NotificationToken = exports.MessageTemplate = exports.Device = exports.Chat = exports.AppStartScreen = exports.MetaData = exports.Company = exports.PotentialUser = exports.Loyalty = exports.SavedSearch = exports.Favorite = exports.Wallet = exports.Permission = exports.Role = exports.User = void 0;
|
|
41
41
|
// common
|
|
42
42
|
exports.LocalizedName = __importStar(require("./common/LocalizedName"));
|
|
43
43
|
exports.Response = __importStar(require("./common/Response"));
|
|
@@ -91,6 +91,8 @@ exports.EventBirthday = __importStar(require("./events/EventBirthday"));
|
|
|
91
91
|
exports.EventOccasion = __importStar(require("./events/EventOccasion"));
|
|
92
92
|
exports.EventVenue = __importStar(require("./events/EventVenue"));
|
|
93
93
|
exports.EventHost = __importStar(require("./events/EventHost"));
|
|
94
|
+
exports.EventDay = __importStar(require("./events/EventDay"));
|
|
95
|
+
exports.EventInvited = __importStar(require("./events/EventInvited"));
|
|
94
96
|
// user
|
|
95
97
|
exports.User = __importStar(require("./user/User"));
|
|
96
98
|
exports.Role = __importStar(require("./user/Role"));
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ad's auto-generated title (the page title, the heading and what Google shows).
|
|
3
|
+
* Ads keep their own title field empty, so the title is built from the ad's details:
|
|
4
|
+
* - property: "<offer type> <category> في <city>"
|
|
5
|
+
* - motor: "<category> | <offer type> سيارة في <city>"
|
|
6
|
+
* - otherwise (or when details are missing): the ad's own title, else the category name
|
|
7
|
+
*
|
|
8
|
+
* The backend saves it in ads.seo_title on add/update, so pages read it without building it.
|
|
9
|
+
*/
|
|
10
|
+
export type AdSeoTitleSource = {
|
|
11
|
+
title?: string | null;
|
|
12
|
+
subject_type?: string | null;
|
|
13
|
+
category?: {
|
|
14
|
+
name?: string | null;
|
|
15
|
+
} | null;
|
|
16
|
+
property?: {
|
|
17
|
+
offerType?: {
|
|
18
|
+
name?: {
|
|
19
|
+
ar?: string | null;
|
|
20
|
+
} | null;
|
|
21
|
+
} | null;
|
|
22
|
+
} | null;
|
|
23
|
+
motor?: {
|
|
24
|
+
offerType?: {
|
|
25
|
+
name?: {
|
|
26
|
+
ar?: string | null;
|
|
27
|
+
} | null;
|
|
28
|
+
} | null;
|
|
29
|
+
} | null;
|
|
30
|
+
/** The ad's city (the second level of its admin boundary path) */
|
|
31
|
+
adminBoundary?: {
|
|
32
|
+
name?: string | null;
|
|
33
|
+
} | null;
|
|
34
|
+
};
|
|
35
|
+
export declare function buildAdSeoTitle(ad?: AdSeoTitleSource | null): string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildAdSeoTitle = buildAdSeoTitle;
|
|
4
|
+
const rtl = (text) => `${text}`;
|
|
5
|
+
const ltr = (text) => `${text}`;
|
|
6
|
+
function buildAdSeoTitle(ad) {
|
|
7
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
8
|
+
if (!ad)
|
|
9
|
+
return "Deallony";
|
|
10
|
+
const categoryName = (_b = (_a = ad.category) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : undefined;
|
|
11
|
+
let title = ((_c = ad.title) === null || _c === void 0 ? void 0 : _c.trim()) || categoryName;
|
|
12
|
+
if (ad.subject_type === "properties") {
|
|
13
|
+
const offer = (_f = (_e = (_d = ad.property) === null || _d === void 0 ? void 0 : _d.offerType) === null || _e === void 0 ? void 0 : _e.name) === null || _f === void 0 ? void 0 : _f.ar;
|
|
14
|
+
if (offer && categoryName) {
|
|
15
|
+
title = offer + " " + categoryName + " في " + ((_g = ad.adminBoundary) === null || _g === void 0 ? void 0 : _g.name);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (ad.subject_type === "motors") {
|
|
19
|
+
const offer = (_k = (_j = (_h = ad.motor) === null || _h === void 0 ? void 0 : _h.offerType) === null || _j === void 0 ? void 0 : _j.name) === null || _k === void 0 ? void 0 : _k.ar;
|
|
20
|
+
if (offer && categoryName) {
|
|
21
|
+
const arabicMain = rtl(`${offer} سيارة في ${(_l = ad.adminBoundary) === null || _l === void 0 ? void 0 : _l.name}`);
|
|
22
|
+
title = `${ltr(categoryName)} | ${arabicMain}`;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return title || "Deallony";
|
|
26
|
+
}
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -29,6 +29,8 @@ export const EventCustomizationSection = {
|
|
|
29
29
|
RSVP: "rsvp",
|
|
30
30
|
MUSIC: "music",
|
|
31
31
|
DRESS_CODE: "dress_code",
|
|
32
|
+
ATTENDANCE: "attendance",
|
|
33
|
+
VIDEO: "video",
|
|
32
34
|
};
|
|
33
35
|
export const EventCustomizationSectionOptions = [
|
|
34
36
|
{ value: "countdown", name: { en: "Countdown", ar: "العد التنازلي" } },
|
|
@@ -38,8 +40,26 @@ export const EventCustomizationSectionOptions = [
|
|
|
38
40
|
{ value: "rsvp", name: { en: "RSVP", ar: "تأكيد الحضور" } },
|
|
39
41
|
{ value: "music", name: { en: "Music", ar: "الموسيقى" } },
|
|
40
42
|
{ value: "dress_code", name: { en: "Dress code", ar: "اللباس المطلوب" } },
|
|
43
|
+
{ value: "attendance", name: { en: "Attendance details", ar: "تفاصيل الحضور" } },
|
|
44
|
+
{ value: "video", name: { en: "Video", ar: "الفيديو" } },
|
|
41
45
|
];
|
|
46
|
+
/** Invitation video (customization.cover_video): one per event, checked in the app before upload */
|
|
47
|
+
export const EVENT_COVER_VIDEO_MAX_SECONDS = 60;
|
|
48
|
+
export const EVENT_COVER_VIDEO_MAX_BYTES = 100 * 1024 * 1024;
|
|
49
|
+
export const EVENT_COVER_VIDEO_TYPES = ["video/mp4", "video/quicktime", "video/webm", "video/x-m4v"];
|
|
42
50
|
export const EVENT_CUSTOMIZATION_TEXT_MAX = 160;
|
|
51
|
+
/** Children / food line on the invitation: defaults, owner text limit and ready phrases */
|
|
52
|
+
export const EVENT_ATTENDANCE_TEXT_MAX = 60;
|
|
53
|
+
export const EventAttendanceTexts = {
|
|
54
|
+
children: {
|
|
55
|
+
default: "جنة الأطفال منازلهم",
|
|
56
|
+
suggestions: ["جنة الأطفال منازلهم", "نعتذر عن اصطحاب الأطفال", "الحفل للكبار فقط", "نتمنى لأطفالكم ليلة هانئة في البيت"],
|
|
57
|
+
},
|
|
58
|
+
food: {
|
|
59
|
+
default: "عشاكم بيحلا معنا",
|
|
60
|
+
suggestions: ["عشاكم بيحلا معنا", "يسعدنا أن تشاركونا العشاء", "بوفيه مفتوح بعد الحفل", "ضيافة وعشاء"],
|
|
61
|
+
},
|
|
62
|
+
};
|
|
43
63
|
/** How the invitation opens for a guest; no value keeps the template's own opening */
|
|
44
64
|
export const EventCustomizationOpening = {
|
|
45
65
|
NONE: "none",
|
|
@@ -22,9 +22,9 @@ export const EventTemplate = {
|
|
|
22
22
|
ENGAGEMENT_ROSE_ARCH: { value: 'engagement-rose-arch', name: { en: 'Rose arch', ar: 'قوس الورد' }, event_types: ['engagement'], photos: 1 },
|
|
23
23
|
ENGAGEMENT_FULL_MOMENT: { value: 'engagement-full-moment', name: { en: 'Full moment', ar: 'لحظة كاملة' }, event_types: ['engagement'], photos: 1 },
|
|
24
24
|
ENGAGEMENT_SEALED_LETTER: { value: 'engagement-sealed-letter', name: { en: 'Sealed letter', ar: 'رسالة مختومة' }, event_types: ['engagement'], photos: 1 },
|
|
25
|
-
MARRIAGE_CONTRACT: { value: 'marriage-contract', name: { en: 'The contract', ar: 'وثيقة العقد' }, event_types: ['marriage'], photos: 1 },
|
|
26
|
-
MARRIAGE_STAR_MEDALLION: { value: 'marriage-star-medallion', name: { en: 'Star medallion', ar: 'ميدالية النجمة' }, event_types: ['marriage'], photos: 1 },
|
|
27
|
-
MARRIAGE_MASHRABIYA: { value: 'marriage-mashrabiya', name: { en: 'Mashrabiya', ar: 'نافذة المشربية' }, event_types: ['marriage'], photos: 1 },
|
|
25
|
+
MARRIAGE_CONTRACT: { value: 'marriage-contract', name: { en: 'The contract', ar: 'وثيقة العقد' }, event_types: ['wedding', 'marriage'], photos: 1 },
|
|
26
|
+
MARRIAGE_STAR_MEDALLION: { value: 'marriage-star-medallion', name: { en: 'Star medallion', ar: 'ميدالية النجمة' }, event_types: ['wedding', 'marriage'], photos: 1 },
|
|
27
|
+
MARRIAGE_MASHRABIYA: { value: 'marriage-mashrabiya', name: { en: 'Mashrabiya', ar: 'نافذة المشربية' }, event_types: ['wedding', 'marriage'], photos: 1 },
|
|
28
28
|
PROPOSAL_ONE_QUESTION: { value: 'proposal-one-question', name: { en: 'One question', ar: 'سؤال واحد' }, event_types: ['proposal'], photos: 1 },
|
|
29
29
|
PROPOSAL_WITNESS_TICKET: { value: 'proposal-witness-ticket', name: { en: 'Witness ticket', ar: 'تذكرة شاهد' }, event_types: ['proposal'], photos: 1 },
|
|
30
30
|
PROPOSAL_CANDLELIGHT: { value: 'proposal-candlelight', name: { en: 'Candlelight', ar: 'ضوء الشموع' }, event_types: ['proposal'], photos: 1 },
|
|
@@ -12,7 +12,8 @@ export const EventTypeGroups = {
|
|
|
12
12
|
export const EventTypes = {
|
|
13
13
|
WEDDING: { value: 'wedding', name: { en: 'Wedding', ar: 'زفاف' }, group: 'celebrations', details: 'wedding' },
|
|
14
14
|
ENGAGEMENT: { value: 'engagement', name: { en: 'Engagement', ar: 'حفلة خطبة' }, group: 'celebrations', details: 'wedding' },
|
|
15
|
-
|
|
15
|
+
/** Folded into the wedding (2026-11): no longer offered, kept so saved events still open */
|
|
16
|
+
MARRIAGE: { value: 'marriage', name: { en: 'Marriage contract', ar: 'حفل زواج' }, group: 'celebrations', details: 'wedding', hidden: true },
|
|
16
17
|
PROPOSAL: { value: 'proposal', name: { en: 'Proposal', ar: 'حفل Proposal' }, group: 'celebrations', details: 'occasion' },
|
|
17
18
|
BACHELOR: { value: 'bachelor', name: { en: 'Bachelor party', ar: 'حفل توديع عزوبية' }, group: 'celebrations', details: 'occasion' },
|
|
18
19
|
BIRTHDAY: { value: 'birthday', name: { en: 'Birthday', ar: 'عيد ميلاد' }, group: 'family', details: 'occasion' },
|
|
@@ -27,12 +28,18 @@ export const EventTypes = {
|
|
|
27
28
|
GENERAL: { value: 'general', name: { en: 'General party', ar: 'حفلة عامة' }, group: 'business', details: 'occasion' },
|
|
28
29
|
};
|
|
29
30
|
export const EventTypeValues = Object.values(EventTypes).map((t) => t.value);
|
|
30
|
-
export const EventTypeOptions = Object.values(EventTypes).map((type) =>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
export const EventTypeOptions = Object.values(EventTypes).map((type) => {
|
|
32
|
+
var _a;
|
|
33
|
+
return ({
|
|
34
|
+
value: type.value,
|
|
35
|
+
name: type.name,
|
|
36
|
+
group: type.group,
|
|
37
|
+
details: type.details,
|
|
38
|
+
hidden: (_a = type.hidden) !== null && _a !== void 0 ? _a : false,
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
/** Types offered when creating an invitation (hidden ones are left out) */
|
|
42
|
+
export const EventTypeOfferedOptions = EventTypeOptions.filter((t) => !t.hidden);
|
|
36
43
|
export const findEventType = (value) => { var _a; return (_a = EventTypeOptions.find((t) => t.value === (value || 'wedding'))) !== null && _a !== void 0 ? _a : null; };
|
|
37
44
|
/** Types whose details are a couple stored in event.wedding (events without a type are weddings) */
|
|
38
45
|
export const isCoupleEventType = (value) => { var _a, _b; return ((_b = (_a = findEventType(value)) === null || _a === void 0 ? void 0 : _a.details) !== null && _b !== void 0 ? _b : 'wedding') === 'wedding'; };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Invitation style of a wedding (also used by engagement and marriage, which share event.wedding).
|
|
3
|
-
* muslim = the Islamic opening
|
|
3
|
+
* muslim = the Islamic opening (bismillah) and dua. No Quran excerpt (removed 2026-11-08 by owner request).
|
|
4
4
|
* general = social congratulations only: names, place, date, program. Suits Christian weddings.
|
|
5
5
|
*
|
|
6
6
|
* Content rule (owner decision 2026-11-04): no Christian religious symbols, creeds, Bible verses or rites
|
|
@@ -16,8 +16,8 @@ export const EventWeddingReligionNames = {
|
|
|
16
16
|
muslim: {
|
|
17
17
|
en: "Islamic",
|
|
18
18
|
ar: "إسلامي",
|
|
19
|
-
hint_en: "Bismillah
|
|
20
|
-
hint_ar: "البسملة
|
|
19
|
+
hint_en: "Bismillah and a dua for the couple.",
|
|
20
|
+
hint_ar: "البسملة ودعاء للعروسين.",
|
|
21
21
|
},
|
|
22
22
|
general: {
|
|
23
23
|
en: "General",
|
|
@@ -31,27 +31,6 @@ export const EventWeddingReligionOptions = EventWeddingReligionValues.map((value
|
|
|
31
31
|
name: EventWeddingReligionNames[value],
|
|
32
32
|
}));
|
|
33
33
|
export const EventWeddingVerses = [
|
|
34
|
-
{
|
|
35
|
-
value: "rum-21",
|
|
36
|
-
religion: "muslim",
|
|
37
|
-
text: "﴿ وَمِنْ آيَاتِهِ أَنْ خَلَقَ لَكُمْ مِنْ أَنْفُسِكُمْ أَزْوَاجًا لِتَسْكُنُوا إِلَيْهَا وَجَعَلَ بَيْنَكُمْ مَوَدَّةً وَرَحْمَةً ﴾",
|
|
38
|
-
reference: "سورة الروم - آية ٢١",
|
|
39
|
-
label: { en: "Ar-Rum 21", ar: "سورة الروم - آية ٢١" },
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
value: "furqan-74",
|
|
43
|
-
religion: "muslim",
|
|
44
|
-
text: "﴿ رَبَّنَا هَبْ لَنَا مِنْ أَزْوَاجِنَا وَذُرِّيَّاتِنَا قُرَّةَ أَعْيُنٍ وَاجْعَلْنَا لِلْمُتَّقِينَ إِمَامًا ﴾",
|
|
45
|
-
reference: "سورة الفرقان - آية ٧٤",
|
|
46
|
-
label: { en: "Al-Furqan 74", ar: "سورة الفرقان - آية ٧٤" },
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
value: "rum-mawadda",
|
|
50
|
-
religion: "muslim",
|
|
51
|
-
text: "﴿ وَجَعَلَ بَيْنَكُم مَّوَدَّةً وَرَحْمَةً ﴾",
|
|
52
|
-
reference: "سورة الروم",
|
|
53
|
-
label: { en: "Mawadda wa rahma", ar: "وجعل بينكم مودة ورحمة" },
|
|
54
|
-
},
|
|
55
34
|
{
|
|
56
35
|
value: "together",
|
|
57
36
|
religion: "general",
|
|
@@ -77,9 +56,15 @@ export const EventWeddingVerses = [
|
|
|
77
56
|
/** General style only: the owner writes the couple's words by hand (event.wedding.custom_verse) */
|
|
78
57
|
export const EVENT_WEDDING_CUSTOM_VERSE = "custom";
|
|
79
58
|
export const EVENT_WEDDING_CUSTOM_VERSE_MAX = 160;
|
|
59
|
+
/**
|
|
60
|
+
* Quran excerpt keys from before 2026-11-08. Still accepted so older apps can save,
|
|
61
|
+
* but the backend drops them and no invitation shows them any more.
|
|
62
|
+
*/
|
|
63
|
+
export const EVENT_WEDDING_LEGACY_VERSE_KEYS = ["rum-21", "furqan-74", "rum-mawadda"];
|
|
80
64
|
export const EventWeddingVerseValues = [
|
|
81
65
|
EVENT_WEDDING_CUSTOM_VERSE,
|
|
82
66
|
...EventWeddingVerses.map((v) => v.value),
|
|
67
|
+
...EVENT_WEDDING_LEGACY_VERSE_KEYS,
|
|
83
68
|
];
|
|
84
69
|
/** The hand-written text applies only to the general style */
|
|
85
70
|
export const eventWeddingCustomVerse = (verseKey, religion, customVerse) => verseKey === EVENT_WEDDING_CUSTOM_VERSE && normalizeEventWeddingReligion(religion) === "general"
|
|
@@ -88,7 +73,7 @@ export const eventWeddingCustomVerse = (verseKey, religion, customVerse) => vers
|
|
|
88
73
|
export const EventWeddingReligionTextsMap = {
|
|
89
74
|
muslim: {
|
|
90
75
|
opening: "بسم الله الرحمن الرحيم",
|
|
91
|
-
verse_title:
|
|
76
|
+
verse_title: null,
|
|
92
77
|
blessing: "اللهم بارك لهما وبارك عليهما واجمع بينهما في خير، واجعل أيامهما مودة ورحمة وسكينة.",
|
|
93
78
|
blessing_title: "دعاء",
|
|
94
79
|
symbol: "۞",
|
|
@@ -109,7 +94,7 @@ export const normalizeEventWeddingReligion = (value) => EventWeddingReligionValu
|
|
|
109
94
|
? value
|
|
110
95
|
: DEFAULT_EVENT_WEDDING_RELIGION;
|
|
111
96
|
export const eventWeddingVersesFor = (religion) => EventWeddingVerses.filter((v) => v.religion === normalizeEventWeddingReligion(religion));
|
|
112
|
-
/** The saved
|
|
97
|
+
/** The saved phrase when it belongs to the style, otherwise the style's first one (undefined for muslim) */
|
|
113
98
|
export const findEventWeddingVerse = (value, religion) => {
|
|
114
99
|
var _a;
|
|
115
100
|
const list = eventWeddingVersesFor(religion);
|
|
@@ -203,6 +203,10 @@ export const APP_ROUTES = {
|
|
|
203
203
|
newOfType: (eventType) => ({ pathname: "/event/new", params: { personal: "1", event_type: eventType } }),
|
|
204
204
|
start: () => ({ pathname: "/event/start" }),
|
|
205
205
|
mine: () => ({ pathname: "/event/mine" }),
|
|
206
|
+
/** «دعواتي»: the events the user was invited to, as a chip of «مناسباتي» */
|
|
207
|
+
invitations: () => ({ pathname: "/event/mine", params: { tab: "invited" } }),
|
|
208
|
+
/** One event the user was invited to, as a guest sees it */
|
|
209
|
+
invited: (eventId) => ({ pathname: "/event/invited/[id]", params: { id: eventId } }),
|
|
206
210
|
/** Upcoming public events (optionally of one venue) */
|
|
207
211
|
upcoming: (venueId) => venueId ? { pathname: "/event/upcoming", params: { venue_id: venueId } } : { pathname: "/event/upcoming" },
|
|
208
212
|
publish: (id) => ({ pathname: "/event/publish/[id]", params: { id } }),
|