wedance-shared 1.0.19 → 1.0.20

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.
Files changed (55) hide show
  1. package/dist/event.d.ts +1 -0
  2. package/dist/festivals/festival.d.ts +9 -9
  3. package/dist/index.d.ts +2 -9
  4. package/dist/index.js +2 -9
  5. package/dist/index.js.map +1 -1
  6. package/dist/types/analytics.d.ts +33 -0
  7. package/dist/types/analytics.js +2 -0
  8. package/dist/types/analytics.js.map +1 -0
  9. package/dist/types/city.d.ts +36 -0
  10. package/dist/types/city.js +44 -0
  11. package/dist/types/city.js.map +1 -0
  12. package/dist/types/event.d.ts +128 -0
  13. package/dist/types/event.js +2 -0
  14. package/dist/types/event.js.map +1 -0
  15. package/dist/types/festivals/festival.d.ts +60 -0
  16. package/dist/types/festivals/festival.js +2 -0
  17. package/dist/types/festivals/festival.js.map +1 -0
  18. package/dist/types/festivals/index.d.ts +2 -0
  19. package/dist/types/festivals/index.js +3 -0
  20. package/dist/types/festivals/index.js.map +1 -0
  21. package/dist/types/festivals/user.d.ts +20 -0
  22. package/dist/types/festivals/user.js +2 -0
  23. package/dist/types/festivals/user.js.map +1 -0
  24. package/dist/types/index.d.ts +8 -0
  25. package/dist/types/index.js +11 -0
  26. package/dist/types/index.js.map +1 -0
  27. package/dist/types/organizer.d.ts +16 -0
  28. package/dist/types/organizer.js +2 -0
  29. package/dist/types/organizer.js.map +1 -0
  30. package/dist/types/other.d.ts +24 -0
  31. package/dist/types/other.js +2 -0
  32. package/dist/types/other.js.map +1 -0
  33. package/dist/types/ticket.d.ts +129 -0
  34. package/dist/types/ticket.js +2 -0
  35. package/dist/types/ticket.js.map +1 -0
  36. package/dist/types/user.d.ts +40 -0
  37. package/dist/types/user.js +2 -0
  38. package/dist/types/user.js.map +1 -0
  39. package/dist/utils/date.d.ts +42 -0
  40. package/dist/utils/date.js +93 -0
  41. package/dist/utils/date.js.map +1 -0
  42. package/package.json +3 -2
  43. package/src/index.ts +2 -9
  44. package/src/{event.ts → types/event.ts} +1 -0
  45. package/src/{festivals → types/festivals}/festival.ts +9 -11
  46. package/src/types/festivals/index.ts +2 -0
  47. package/src/types/index.ts +11 -0
  48. package/src/utils/date.ts +116 -0
  49. /package/src/{analytics.ts → types/analytics.ts} +0 -0
  50. /package/src/{city.ts → types/city.ts} +0 -0
  51. /package/src/{festivals → types/festivals}/user.ts +0 -0
  52. /package/src/{organizer.ts → types/organizer.ts} +0 -0
  53. /package/src/{other.ts → types/other.ts} +0 -0
  54. /package/src/{ticket.ts → types/ticket.ts} +0 -0
  55. /package/src/{user.ts → types/user.ts} +0 -0
package/dist/event.d.ts CHANGED
@@ -9,6 +9,7 @@ export type Organizer = {
9
9
  email?: string;
10
10
  };
11
11
  export type Links = {
12
+ paymentLink?: string;
12
13
  instagram?: string;
13
14
  facebook?: string;
14
15
  website?: string;
@@ -1,5 +1,6 @@
1
1
  import { Timestamp } from "@react-native-firebase/firestore";
2
2
  import { Links } from "../event";
3
+ import { EventTicket } from "wedance-shared";
3
4
  /**
4
5
  * This is the type of the data we get from the server
5
6
  * */
@@ -8,14 +9,12 @@ export type FestivalData = {
8
9
  title: string;
9
10
  from: Timestamp;
10
11
  until: Timestamp;
11
- organizerId: string;
12
+ organizerId: string[];
12
13
  description: string;
13
14
  location: FestivalLocation[];
14
15
  genre?: FestivalGenre[];
15
16
  tags?: string[];
16
17
  imageData: FestivalImageData[];
17
- countryCode: string;
18
- region: Region[];
19
18
  priceRange?: {
20
19
  min: number;
21
20
  max: number;
@@ -28,6 +27,7 @@ export type FestivalData = {
28
27
  links: Links;
29
28
  isFree: boolean;
30
29
  artists: FestivalArtist[];
30
+ tickets?: EventTicket[];
31
31
  };
32
32
  type FestivalGenre = "salsa" | "bachata" | "kizomba" | "zouk";
33
33
  type FestivalImageData = {
@@ -35,10 +35,10 @@ type FestivalImageData = {
35
35
  alt?: string;
36
36
  blurhash?: string;
37
37
  };
38
- type FestivalLocation = {
39
- id?: string;
38
+ export type FestivalLocation = {
40
39
  city: string;
41
40
  countryCode: string;
41
+ country: string;
42
42
  address?: string;
43
43
  venue?: string;
44
44
  geoLocation?: {
@@ -46,15 +46,15 @@ type FestivalLocation = {
46
46
  lng: number;
47
47
  };
48
48
  timeZone: string;
49
- region?: Region[];
49
+ region: Region[];
50
50
  };
51
- type FestivalArtist = {
51
+ export type FestivalArtist = {
52
52
  id: string;
53
53
  name: string;
54
54
  image: string;
55
55
  imageUrl: string;
56
56
  role: FestivalArtistRole;
57
57
  };
58
- type FestivalArtistRole = "dj" | "dancer" | "mc" | "guest-dancer" | "organizer" | "media";
59
- type Region = "Nordics" | "Baltics" | "Western Europe" | "Eastern Europe" | "Southern Europe" | "Central Europe" | "Asia" | "Africa";
58
+ export type FestivalArtistRole = "dj" | "dancer" | "mc" | "guest-dancer" | "organizer" | "media";
59
+ export type Region = "Nordics" | "Baltics" | "Western Europe" | "Eastern Europe" | "Southern Europe" | "Central Europe" | "Asia" | "Africa";
60
60
  export {};
package/dist/index.d.ts CHANGED
@@ -1,9 +1,2 @@
1
- export * from "./event";
2
- export * from "./organizer";
3
- export * from "./ticket";
4
- export * from "./user";
5
- export * from "./city";
6
- export * from "./other";
7
- export * from "./analytics";
8
- export * from "./festivals/festival";
9
- export * from "./festivals/user";
1
+ export * from "./types";
2
+ export * from "./utils/date";
package/dist/index.js CHANGED
@@ -1,10 +1,3 @@
1
- export * from "./event";
2
- export * from "./organizer";
3
- export * from "./ticket";
4
- export * from "./user";
5
- export * from "./city";
6
- export * from "./other";
7
- export * from "./analytics";
8
- export * from "./festivals/festival";
9
- export * from "./festivals/user";
1
+ export * from "./types";
2
+ export * from "./utils/date";
10
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { Timestamp } from "@react-native-firebase/firestore";
2
+ export type GoogleAnalyticsResponse = {
3
+ dimensionHeaders: {
4
+ name: string;
5
+ }[];
6
+ metricHeaders: {
7
+ name: string;
8
+ type: string;
9
+ }[];
10
+ rows: {
11
+ dimensionValues: {
12
+ value: string;
13
+ }[];
14
+ metricValues: {
15
+ value: string;
16
+ }[];
17
+ }[];
18
+ rowCount: number;
19
+ };
20
+ export type EventAnalyticsMetrics = {
21
+ eventCount: string;
22
+ totalUsers: string;
23
+ eventId: string;
24
+ };
25
+ export type DailyAnalyticsReport = {
26
+ createdAt: Timestamp;
27
+ data: EventAnalyticsMetrics[];
28
+ reportDate: string;
29
+ dateRange: {
30
+ endDate: string;
31
+ startDate: string;
32
+ };
33
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/types/analytics.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ type CityData = {
2
+ city: "helsinki";
3
+ country: "fi";
4
+ coordinates: [60.1695, 24.9354];
5
+ } | {
6
+ city: "tampere";
7
+ country: "fi";
8
+ coordinates: [61.4978, 23.761];
9
+ } | {
10
+ city: "oslo";
11
+ country: "no";
12
+ coordinates: [59.9139, 10.7522];
13
+ } | {
14
+ city: "tallinn";
15
+ country: "ee";
16
+ coordinates: [59.437, 24.7536];
17
+ } | {
18
+ city: "copenhagen";
19
+ country: "dk";
20
+ coordinates: [55.6761, 12.5683];
21
+ } | {
22
+ city: "oulu";
23
+ country: "fi";
24
+ coordinates: [65.012, 25.468];
25
+ };
26
+ export declare const LIST_CITIES: CityData[];
27
+ export type City = CityData;
28
+ export type CityName = CityData["city"];
29
+ export type CountryCode = CityData["country"];
30
+ export declare enum Timezone {
31
+ FINLAND = "Europe/Helsinki",
32
+ DENMARK = "Europe/Copenhagen",
33
+ SWEDEN = "Europe/Stockholm",
34
+ NORWAY = "Europe/Oslo"
35
+ }
36
+ export {};
@@ -0,0 +1,44 @@
1
+ export const LIST_CITIES = [
2
+ {
3
+ city: "helsinki",
4
+ country: "fi",
5
+ coordinates: [60.1695, 24.9354]
6
+ },
7
+ {
8
+ city: "tampere",
9
+ country: "fi",
10
+ coordinates: [61.4978, 23.761]
11
+ },
12
+ {
13
+ city: "oslo",
14
+ country: "no",
15
+ coordinates: [59.9139, 10.7522]
16
+ },
17
+ // {
18
+ // city: 'stockholm',
19
+ // country: 'se',
20
+ // },
21
+ {
22
+ city: "tallinn",
23
+ country: "ee",
24
+ coordinates: [59.437, 24.7536]
25
+ },
26
+ {
27
+ city: "copenhagen",
28
+ country: "dk",
29
+ coordinates: [55.6761, 12.5683]
30
+ },
31
+ {
32
+ city: "oulu",
33
+ country: "fi",
34
+ coordinates: [65.012, 25.468]
35
+ }
36
+ ];
37
+ export var Timezone;
38
+ (function (Timezone) {
39
+ Timezone["FINLAND"] = "Europe/Helsinki";
40
+ Timezone["DENMARK"] = "Europe/Copenhagen";
41
+ Timezone["SWEDEN"] = "Europe/Stockholm";
42
+ Timezone["NORWAY"] = "Europe/Oslo";
43
+ })(Timezone || (Timezone = {}));
44
+ //# sourceMappingURL=city.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"city.js","sourceRoot":"","sources":["../../src/types/city.ts"],"names":[],"mappings":"AAgCA,MAAM,CAAC,MAAM,WAAW,GAAe;IACrC;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;KAChC;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;KAC/B;IACD;QACE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;KAChC;IACD,IAAI;IACJ,uBAAuB;IACvB,mBAAmB;IACnB,KAAK;IACL;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;KAC/B;IACD;QACE,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;KAChC;IACD;QACE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;KAC9B;CACF,CAAC;AAMF,MAAM,CAAN,IAAY,QAKX;AALD,WAAY,QAAQ;IAClB,uCAA2B,CAAA;IAC3B,yCAA6B,CAAA;IAC7B,uCAA2B,CAAA;IAC3B,kCAAsB,CAAA;AACxB,CAAC,EALW,QAAQ,KAAR,QAAQ,QAKnB"}
@@ -0,0 +1,128 @@
1
+ import { Timestamp } from "@react-native-firebase/firestore";
2
+ import { City } from "./city";
3
+ import { OrganizerName } from "./organizer";
4
+ import { EventTicket } from "./ticket";
5
+ import { UserBadge } from "./user";
6
+ export type DanceTag = "salsa" | "kizomba" | "bachata" | "zouk";
7
+ export type Organizer = {
8
+ name: OrganizerName;
9
+ email?: string;
10
+ };
11
+ export type Links = {
12
+ paymentLink?: string;
13
+ instagram?: string;
14
+ facebook?: string;
15
+ website?: string;
16
+ other?: string;
17
+ };
18
+ export type Location = {
19
+ name: string;
20
+ address?: string;
21
+ };
22
+ export type EventStatus = "draft" | "published" | "cancelled";
23
+ export type ImageData = {
24
+ url: string;
25
+ alt?: string;
26
+ blurhash?: string;
27
+ };
28
+ /**
29
+ * This is the type of the data we get from the server
30
+ * */
31
+ export type EventData = {
32
+ id: string;
33
+ title: string;
34
+ from: string;
35
+ until: string;
36
+ price: number;
37
+ priceProvided: boolean;
38
+ organizer: Organizer;
39
+ description: string;
40
+ location: Location;
41
+ duration?: number;
42
+ tags: DanceTag[];
43
+ links: Links;
44
+ /**
45
+ * Events have international artists
46
+ */
47
+ isInternational: boolean;
48
+ /**
49
+ * Is event private? @deprecated
50
+ */
51
+ isPrivate?: boolean;
52
+ hasSeveralPrices?: boolean;
53
+ createdAt: string;
54
+ lastUpdated?: string;
55
+ publishedSchedule?: boolean;
56
+ schedule: EventSchedule | null;
57
+ addedBy: string;
58
+ updatedBy: string;
59
+ paymentLink: string | null;
60
+ status: EventStatus | null;
61
+ city: City;
62
+ isFestival: boolean | null;
63
+ going: UserBadge[] | null;
64
+ interested: UserBadge[] | null;
65
+ imageData: ImageData;
66
+ eventTickets?: EventTicket[] | null;
67
+ lineup?: LineUpArtist[] | null;
68
+ };
69
+ export type EventCellType = "workshop" | "social" | "break" | "other";
70
+ export type ScheduleItem = {
71
+ id: string;
72
+ headline: string;
73
+ subheader: string | null;
74
+ from: string;
75
+ until: string;
76
+ type: EventCellType;
77
+ level: string | null;
78
+ };
79
+ export type EventSchedule = Record<string, ScheduleItem[]>;
80
+ export type LineUpArtist = {
81
+ id: string;
82
+ name: string;
83
+ description: string;
84
+ image: string;
85
+ imageUrl: string;
86
+ };
87
+ export type Featured = {
88
+ /**
89
+ * ID of the promotion
90
+ */
91
+ id: string;
92
+ /**
93
+ * ID of the event being promoted
94
+ */
95
+ eventId: string;
96
+ /**
97
+ * Cities where this promotion should be shown
98
+ */
99
+ cities: City["city"][];
100
+ /**
101
+ * Priority level for displaying multiple featured events (higher = more prominent)
102
+ */
103
+ priority: number;
104
+ /**
105
+ * Optional custom promotion message
106
+ */
107
+ promotionalText?: string;
108
+ /**
109
+ * Who created this promotion
110
+ */
111
+ createdBy: string;
112
+ /**
113
+ * When this promotion was created (ISO date string)
114
+ */
115
+ createdAt: Timestamp;
116
+ updatedAt: Timestamp;
117
+ /**
118
+ * Whether the promotion is currently active
119
+ */
120
+ isActive: boolean;
121
+ /**
122
+ * Date range of the promotion
123
+ */
124
+ dateRange: {
125
+ startDate: Timestamp;
126
+ endDate: Timestamp;
127
+ };
128
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.js","sourceRoot":"","sources":["../../src/types/event.ts"],"names":[],"mappings":""}
@@ -0,0 +1,60 @@
1
+ import { Timestamp } from "@react-native-firebase/firestore";
2
+ import { Links } from "../event";
3
+ import { EventTicket } from "wedance-shared";
4
+ /**
5
+ * This is the type of the data we get from the server
6
+ * */
7
+ export type FestivalData = {
8
+ id: string;
9
+ title: string;
10
+ from: Timestamp;
11
+ until: Timestamp;
12
+ organizerId: string[];
13
+ description: string;
14
+ location: FestivalLocation[];
15
+ genre?: FestivalGenre[];
16
+ tags?: string[];
17
+ imageData: FestivalImageData[];
18
+ priceRange?: {
19
+ min: number;
20
+ max: number;
21
+ currency: string;
22
+ };
23
+ createdAt: Timestamp;
24
+ updatedAt: Timestamp;
25
+ createdBy: string;
26
+ updatedBy: string;
27
+ links: Links;
28
+ isFree: boolean;
29
+ artists: FestivalArtist[];
30
+ tickets?: EventTicket[];
31
+ };
32
+ type FestivalGenre = "salsa" | "bachata" | "kizomba" | "zouk";
33
+ type FestivalImageData = {
34
+ url: string;
35
+ alt?: string;
36
+ blurhash?: string;
37
+ };
38
+ export type FestivalLocation = {
39
+ city: string;
40
+ countryCode: string;
41
+ country: string;
42
+ address?: string;
43
+ venue?: string;
44
+ geoLocation?: {
45
+ lat: number;
46
+ lng: number;
47
+ };
48
+ timeZone: string;
49
+ region: Region[];
50
+ };
51
+ export type FestivalArtist = {
52
+ id: string;
53
+ name: string;
54
+ image: string;
55
+ imageUrl: string;
56
+ role: FestivalArtistRole;
57
+ };
58
+ export type FestivalArtistRole = "dj" | "dancer" | "mc" | "guest-dancer" | "organizer" | "media";
59
+ export type Region = "Nordics" | "Baltics" | "Western Europe" | "Eastern Europe" | "Southern Europe" | "Central Europe" | "Asia" | "Africa";
60
+ export {};
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=festival.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"festival.js","sourceRoot":"","sources":["../../../src/types/festivals/festival.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export * from "./festival";
2
+ export * from "./user";
@@ -0,0 +1,3 @@
1
+ export * from "./festival";
2
+ export * from "./user";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/festivals/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { Timestamp } from "@react-native-firebase/firestore";
2
+ import { Role } from "../user";
3
+ export type FestivalUser = {
4
+ id: string;
5
+ email: string;
6
+ displayName: string;
7
+ profilePicture?: string;
8
+ favoriteFestivals: string[];
9
+ role: Role;
10
+ basedIn?: string;
11
+ createdAt: Timestamp;
12
+ lastUpdated: Timestamp;
13
+ lastConnected: Timestamp;
14
+ fcmTokens?: string[];
15
+ appVersion: string;
16
+ deviceModel: string;
17
+ platform: string;
18
+ emailVerified: boolean;
19
+ stripeId?: string;
20
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../../src/types/festivals/user.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ export * from "./event";
2
+ export * from "./ticket";
3
+ export * from "./city";
4
+ export * from "./organizer";
5
+ export * from "./user";
6
+ export * from "./other";
7
+ export * from "./analytics";
8
+ export * from "./festivals";
@@ -0,0 +1,11 @@
1
+ // Re-export all types from individual files
2
+ export * from "./event";
3
+ export * from "./ticket";
4
+ export * from "./city";
5
+ export * from "./organizer";
6
+ export * from "./user";
7
+ export * from "./other";
8
+ export * from "./analytics";
9
+ // Re-export from subdirectories
10
+ export * from "./festivals";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAE5B,gCAAgC;AAChC,cAAc,aAAa,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { City } from "./city";
2
+ export type OrganizerName = "SOB Productions" | "Helsinki SBK" | "Avec Dance Club" | "Still Dancing" | "Tanssikoulu SalsaLatina" | "Helsinki Salsa Academy" | "BabaGen" | "Bachata Studio" | "Tanssikoulu BailaBaila" | "Petra & Otso" | "Bachata Helsinki" | "Anton Kargaltsev" | "Salsa Borealis" | "Helsinki Dance Central" | "Ted's Kizomba" | "Urbankiz Helsinki" | "Azembora" | "S-Dance" | "Helsinki Kizomba Studio" | "idance Helsinki" | "Dance Social" | "Tampere Social Dance" | "Azúcar" | "DJ Pies Locos" | "Kizomba Social Tampere" | "Bachata & Kizomba Oulu" | "SALSA Klubi" | "Tanssikoulu Vamos" | "Feels Oulu" | "Bachata Sensual Lovers" | "Tanssikoulu Matleena" | "Merja Tanjunen" | "Fever Dance Oslo" | "Pure Dance Official" | "Dancecity" | "Bachata Monthly" | "Salsakompaniet" | "Bachata Studio Tallinn" | "Casa De Baile" | "Havana Moderna" | "Crazy Lion Events" | "Other";
3
+ export type OrganizerData = {
4
+ id: string;
5
+ name: OrganizerName;
6
+ email?: string;
7
+ website?: string;
8
+ city: City;
9
+ description?: {
10
+ fi: string;
11
+ en: string;
12
+ };
13
+ lastUpdated: string;
14
+ createdAt: string;
15
+ isFlagged: boolean;
16
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=organizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"organizer.js","sourceRoot":"","sources":["../../src/types/organizer.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ export type Language = {
2
+ code: LanguageCode;
3
+ };
4
+ export type LanguageCode = "en-gb" | "fi";
5
+ export type DayPoll = {
6
+ [eventId: string]: string[];
7
+ other: string[];
8
+ };
9
+ export type WeekendPoll = {
10
+ pollId: string;
11
+ createdAt: string;
12
+ friday: DayPoll;
13
+ saturday: DayPoll;
14
+ };
15
+ export type FeatureFlags = {
16
+ multicity: boolean;
17
+ copenhagen: boolean;
18
+ oslo: boolean;
19
+ stockholm: boolean;
20
+ };
21
+ export type RemoteConfigMessageType = {
22
+ severity: "info" | "warning";
23
+ message: string;
24
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=other.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"other.js","sourceRoot":"","sources":["../../src/types/other.ts"],"names":[],"mappings":""}
@@ -0,0 +1,129 @@
1
+ import { Timestamp } from "@react-native-firebase/firestore";
2
+ export type TicketStatus = "Confirmed" | "Cancelled" | "Refunded" | "Expired" | "Used" | "Transferred";
3
+ export type Ticket = {
4
+ /**
5
+ * ID of the ticket
6
+ */
7
+ id: string;
8
+ /**
9
+ * ID of the event ticket
10
+ */
11
+ ticketId: string;
12
+ eventId: string;
13
+ eventName: string;
14
+ eventDate: string;
15
+ purchaseDate: string;
16
+ quantity: number;
17
+ ticketPrice: number;
18
+ ticketType: string;
19
+ previousOwner: string[];
20
+ originalOwnerId: string;
21
+ /**
22
+ * ID of the user who owns the ticket
23
+ */
24
+ owner: string;
25
+ status: TicketStatus;
26
+ isRefundable: boolean;
27
+ isTransferable: boolean;
28
+ paymentId: string;
29
+ appliedCoupon?: {
30
+ code: string;
31
+ discountAmount: number;
32
+ discountType: "fixed" | "percentage";
33
+ };
34
+ originalPrice: number;
35
+ orderNumber: string;
36
+ checkedInAt?: string;
37
+ notes?: string;
38
+ transferredAt?: string;
39
+ refundedAt?: string;
40
+ createdAt: Timestamp;
41
+ updatedAt: Timestamp;
42
+ };
43
+ export type TicketTransfer = {
44
+ type: "transfer";
45
+ fromUserId: string;
46
+ toUserId: string;
47
+ timestamp: Timestamp;
48
+ };
49
+ export type CouponCode = {
50
+ code: string;
51
+ discountAmount: number;
52
+ discountType: "fixed" | "percentage";
53
+ minPurchaseQuantity?: number;
54
+ maxUsage?: number;
55
+ expiryDate?: string;
56
+ };
57
+ export type EventTicket = {
58
+ id: string;
59
+ price: number;
60
+ ticketType: string;
61
+ eventId: string;
62
+ quantity: number;
63
+ amountSold: number;
64
+ coupons?: CouponCode[];
65
+ name: string;
66
+ description?: string;
67
+ maxQuantityPerPurchase?: number;
68
+ minQuantityPerPurchase?: number;
69
+ saleStartDate?: string;
70
+ saleEndDate?: string;
71
+ isEarlyBird?: boolean;
72
+ isTransferable: boolean;
73
+ isRefundable: boolean;
74
+ status: "published" | "draft";
75
+ };
76
+ export type Payment = {
77
+ amount: number;
78
+ amount_capturable: number;
79
+ amount_details: {
80
+ tip: any;
81
+ };
82
+ amount_received: number;
83
+ application: string | null;
84
+ application_fee_amount: number | null;
85
+ automatic_payment_methods: {
86
+ allow_redirects: "always" | "never";
87
+ enabled: boolean;
88
+ };
89
+ canceled_at: string | null;
90
+ cancellation_reason: string | null;
91
+ capture_method: "automatic" | "manual";
92
+ client_secret: string;
93
+ confirmation_method: string;
94
+ created: number;
95
+ currency: string;
96
+ customer: string;
97
+ description: string | null;
98
+ id: string;
99
+ invoice: string | null;
100
+ last_payment_error: string | null;
101
+ latest_charge: string;
102
+ livemode: boolean;
103
+ metadata: Record<string, any>;
104
+ next_action: string | null;
105
+ object: string;
106
+ on_behalf_of: string | null;
107
+ payment_method_types: ("card" | "mobilepay")[];
108
+ payment_method_configuration_details: {
109
+ id: string;
110
+ };
111
+ payment_method_options: {
112
+ card: {
113
+ network?: string;
114
+ request_three_d_secure: string;
115
+ };
116
+ mobilepay: any;
117
+ };
118
+ processing: string | null;
119
+ receipt_email: string;
120
+ review: string | null;
121
+ setup_future_usage: string | null;
122
+ shipping: string | null;
123
+ source: string | null;
124
+ statement_descriptor: string | null;
125
+ statement_descriptor_suffix: string | null;
126
+ status: "succeeded" | string;
127
+ transfer_data: string | null;
128
+ transfer_group: string | null;
129
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ticket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket.js","sourceRoot":"","sources":["../../src/types/ticket.ts"],"names":[],"mappings":""}
@@ -0,0 +1,40 @@
1
+ import { City } from './city';
2
+ import { DanceTag } from './event';
3
+ import { OrganizerName } from './organizer';
4
+ import { Ticket } from './ticket';
5
+ export type Role = 'admin' | 'manager' | 'organiser' | 'user';
6
+ export type User = {
7
+ id: string;
8
+ email: string;
9
+ displayName: string;
10
+ createdAt: string;
11
+ lastUpdated?: string;
12
+ lastConnected?: string;
13
+ savedEvents: string[];
14
+ goingEvents: string[];
15
+ role: Role;
16
+ managerCity?: City;
17
+ organiser?: OrganizerName;
18
+ city: City | null;
19
+ followingOrganisers: OrganizerName[];
20
+ favoriteDance?: DanceTag;
21
+ fcmTokens?: string[];
22
+ notificationPreferences?: NotificationPreferences;
23
+ appVersion?: string;
24
+ deviceModel?: string;
25
+ platform?: string;
26
+ tickets?: Ticket[];
27
+ emailVerified: boolean;
28
+ stripeId?: string;
29
+ };
30
+ export type NotificationPreferences = {
31
+ all: boolean;
32
+ };
33
+ /**
34
+ * This is used to show who is going to the event
35
+ */
36
+ export type UserBadge = {
37
+ id: string;
38
+ displayName: string;
39
+ avatar?: string;
40
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/types/user.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import { Timestamp } from "@react-native-firebase/firestore";
2
+ /**
3
+ * Converts a Firestore Timestamp to a JavaScript Date object
4
+ * @param timestamp Firestore Timestamp or null/undefined
5
+ * @returns JavaScript Date object or null if input is null/undefined
6
+ */
7
+ export declare const timestampToDate: (timestamp: Timestamp | null | undefined) => Date | null;
8
+ /**
9
+ * Converts a JavaScript Date to a Firestore Timestamp
10
+ * @param date JavaScript Date object or null/undefined
11
+ * @returns Firestore Timestamp or null if input is null/undefined
12
+ */
13
+ export declare const dateToTimestamp: (date: Date | null | undefined) => Timestamp | null;
14
+ /**
15
+ * Formats a Firestore Timestamp to a string using the provided format
16
+ * Uses day.js library - install with: npm install dayjs
17
+ * @param timestamp Firestore Timestamp or null/undefined
18
+ * @param formatStr Format string compatible with day.js format function
19
+ * (see https://day.js.org/docs/en/display/format for format options)
20
+ * @param defaultValue Value to return if timestamp is null/undefined
21
+ * @returns Formatted date string or defaultValue if timestamp is null/undefined
22
+ */
23
+ export declare const formatTimestamp: (timestamp: Timestamp | null | undefined, formatStr?: string, defaultValue?: string) => string;
24
+ /**
25
+ * Checks if a Firestore Timestamp is before current time
26
+ * @param timestamp Firestore Timestamp to check
27
+ * @returns boolean indicating if timestamp is in the past
28
+ */
29
+ export declare const isTimestampInPast: (timestamp: Timestamp | null | undefined) => boolean;
30
+ /**
31
+ * Checks if a Firestore Timestamp is after current time
32
+ * @param timestamp Firestore Timestamp to check
33
+ * @returns boolean indicating if timestamp is in the future
34
+ */
35
+ export declare const isTimestampInFuture: (timestamp: Timestamp | null | undefined) => boolean;
36
+ /**
37
+ * Gets the relative time between now and a Firestore Timestamp (e.g. "2 hours ago", "in 3 days")
38
+ * Uses day.js with relativeTime plugin for localized relative time formatting
39
+ * @param timestamp Firestore Timestamp
40
+ * @returns String representation of relative time
41
+ */
42
+ export declare const getRelativeTime: (timestamp: Timestamp | null | undefined) => string;
@@ -0,0 +1,93 @@
1
+ import { Timestamp } from "@react-native-firebase/firestore";
2
+ import dayjs from "dayjs";
3
+ import relativeTime from "dayjs/plugin/relativeTime";
4
+ // Register the relativeTime plugin
5
+ dayjs.extend(relativeTime);
6
+ /**
7
+ * Converts a Firestore Timestamp to a JavaScript Date object
8
+ * @param timestamp Firestore Timestamp or null/undefined
9
+ * @returns JavaScript Date object or null if input is null/undefined
10
+ */
11
+ export const timestampToDate = (timestamp) => {
12
+ if (!timestamp)
13
+ return null;
14
+ return new Date(timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000);
15
+ };
16
+ /**
17
+ * Converts a JavaScript Date to a Firestore Timestamp
18
+ * @param date JavaScript Date object or null/undefined
19
+ * @returns Firestore Timestamp or null if input is null/undefined
20
+ */
21
+ export const dateToTimestamp = (date) => {
22
+ if (!date)
23
+ return null;
24
+ return Timestamp.fromDate(date);
25
+ };
26
+ /**
27
+ * Formats a Firestore Timestamp to a string using the provided format
28
+ * Uses day.js library - install with: npm install dayjs
29
+ * @param timestamp Firestore Timestamp or null/undefined
30
+ * @param formatStr Format string compatible with day.js format function
31
+ * (see https://day.js.org/docs/en/display/format for format options)
32
+ * @param defaultValue Value to return if timestamp is null/undefined
33
+ * @returns Formatted date string or defaultValue if timestamp is null/undefined
34
+ */
35
+ export const formatTimestamp = (timestamp, formatStr = "MMM D, YYYY", defaultValue = "") => {
36
+ if (!timestamp)
37
+ return defaultValue;
38
+ try {
39
+ // Convert timestamp to Date
40
+ const date = new Date(timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000);
41
+ // Use dayjs to format the date according to the format string
42
+ return dayjs(date).format(formatStr);
43
+ }
44
+ catch (error) {
45
+ console.error("Error formatting timestamp:", error);
46
+ return defaultValue;
47
+ }
48
+ };
49
+ /**
50
+ * Checks if a Firestore Timestamp is before current time
51
+ * @param timestamp Firestore Timestamp to check
52
+ * @returns boolean indicating if timestamp is in the past
53
+ */
54
+ export const isTimestampInPast = (timestamp) => {
55
+ if (!timestamp)
56
+ return false;
57
+ // Convert timestamp to milliseconds manually
58
+ const timestampMillis = timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000;
59
+ return timestampMillis < Date.now();
60
+ };
61
+ /**
62
+ * Checks if a Firestore Timestamp is after current time
63
+ * @param timestamp Firestore Timestamp to check
64
+ * @returns boolean indicating if timestamp is in the future
65
+ */
66
+ export const isTimestampInFuture = (timestamp) => {
67
+ if (!timestamp)
68
+ return false;
69
+ // Convert timestamp to milliseconds manually
70
+ const timestampMillis = timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000;
71
+ return timestampMillis > Date.now();
72
+ };
73
+ /**
74
+ * Gets the relative time between now and a Firestore Timestamp (e.g. "2 hours ago", "in 3 days")
75
+ * Uses day.js with relativeTime plugin for localized relative time formatting
76
+ * @param timestamp Firestore Timestamp
77
+ * @returns String representation of relative time
78
+ */
79
+ export const getRelativeTime = (timestamp) => {
80
+ if (!timestamp)
81
+ return "";
82
+ try {
83
+ // Convert timestamp to milliseconds manually
84
+ const timestampMillis = timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000;
85
+ // Use dayjs to get relative time
86
+ return dayjs(timestampMillis).fromNow();
87
+ }
88
+ catch (error) {
89
+ console.error("Error generating relative time:", error);
90
+ return "";
91
+ }
92
+ };
93
+ //# sourceMappingURL=date.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.js","sourceRoot":"","sources":["../../src/utils/date.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,YAAY,MAAM,2BAA2B,CAAC;AAErD,mCAAmC;AACnC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;AAE3B;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,SAAuC,EAC1B,EAAE;IACf,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC;AAC9E,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,IAA6B,EACX,EAAE;IACpB,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,SAAuC,EACvC,YAAoB,aAAa,EACjC,eAAuB,EAAE,EACjB,EAAE;IACV,IAAI,CAAC,SAAS;QAAE,OAAO,YAAY,CAAC;IAEpC,IAAI,CAAC;QACH,4BAA4B;QAC5B,MAAM,IAAI,GAAG,IAAI,IAAI,CACnB,SAAS,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,WAAW,GAAG,OAAO,CAC3D,CAAC;QAEF,8DAA8D;QAC9D,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACpD,OAAO,YAAY,CAAC;IACtB,CAAC;AACH,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,SAAuC,EAC9B,EAAE;IACX,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAE7B,6CAA6C;IAC7C,MAAM,eAAe,GACnB,SAAS,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,WAAW,GAAG,OAAO,CAAC;IAC7D,OAAO,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACtC,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,SAAuC,EAC9B,EAAE;IACX,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAE7B,6CAA6C;IAC7C,MAAM,eAAe,GACnB,SAAS,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,WAAW,GAAG,OAAO,CAAC;IAC7D,OAAO,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACtC,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,SAAuC,EAC/B,EAAE;IACV,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IAE1B,IAAI,CAAC;QACH,6CAA6C;QAC7C,MAAM,eAAe,GACnB,SAAS,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,WAAW,GAAG,OAAO,CAAC;QAE7D,iCAAiC;QACjC,OAAO,KAAK,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;QACxD,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wedance-shared",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "This repository contains shared TypeScript types and interfaces used across multiple WeDance applications:",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -33,6 +33,7 @@
33
33
  },
34
34
  "type": "module",
35
35
  "dependencies": {
36
- "@react-native-firebase/firestore": "21.2.0"
36
+ "@react-native-firebase/firestore": "21.2.0",
37
+ "dayjs": "^1.11.13"
37
38
  }
38
39
  }
package/src/index.ts CHANGED
@@ -1,9 +1,2 @@
1
- export * from "./event";
2
- export * from "./organizer";
3
- export * from "./ticket";
4
- export * from "./user";
5
- export * from "./city";
6
- export * from "./other";
7
- export * from "./analytics";
8
- export * from "./festivals/festival";
9
- export * from "./festivals/user";
1
+ export * from "./types";
2
+ export * from "./utils/date";
@@ -12,6 +12,7 @@ export type Organizer = {
12
12
  };
13
13
 
14
14
  export type Links = {
15
+ paymentLink?: string;
15
16
  instagram?: string;
16
17
  facebook?: string;
17
18
  website?: string;
@@ -1,6 +1,6 @@
1
1
  import { Timestamp } from "@react-native-firebase/firestore";
2
2
  import { Links } from "../event";
3
- import { DanceTag } from "wedance-shared";
3
+ import { DanceTag, EventTicket } from "wedance-shared";
4
4
 
5
5
  /**
6
6
  * This is the type of the data we get from the server
@@ -10,7 +10,7 @@ export type FestivalData = {
10
10
  title: string;
11
11
  from: Timestamp;
12
12
  until: Timestamp;
13
- organizerId: string;
13
+ organizerId: string[];
14
14
  description: string;
15
15
  location: FestivalLocation[];
16
16
 
@@ -19,9 +19,6 @@ export type FestivalData = {
19
19
 
20
20
  imageData: FestivalImageData[];
21
21
 
22
- countryCode: string; // ISO 3166-1 Alpha-2 (e.g., "SE", "FI", "EE")
23
- region: Region[]; // e.g., ["Nordics"], ["Baltics"], ["Europe"]
24
-
25
22
  priceRange?: { min: number; max: number; currency: string };
26
23
 
27
24
  createdAt: Timestamp;
@@ -35,6 +32,7 @@ export type FestivalData = {
35
32
  isFree: boolean;
36
33
 
37
34
  artists: FestivalArtist[];
35
+ tickets?: EventTicket[];
38
36
  };
39
37
 
40
38
  type FestivalGenre = "salsa" | "bachata" | "kizomba" | "zouk";
@@ -45,18 +43,18 @@ type FestivalImageData = {
45
43
  blurhash?: string;
46
44
  };
47
45
 
48
- type FestivalLocation = {
49
- id?: string; // Firestore auto-generates if not provided
46
+ export type FestivalLocation = {
50
47
  city: string; // e.g., "Stockholm"
51
48
  countryCode: string; // ISO 3166-1 (e.g., "SE" for Sweden)
49
+ country: string;
52
50
  address?: string; // Optional detailed address (e.g., "Arenavägen 75")
53
51
  venue?: string; // Optional (e.g., "Avicii Arena")
54
52
  geoLocation?: { lat: number; lng: number }; // For maps
55
53
  timeZone: string; // e.g., "Europe/Stockholm"
56
- region?: Region[]; // e.g., "Nordics", "Baltics"
54
+ region: Region[]; // e.g., "Nordics", "Baltics"
57
55
  };
58
56
 
59
- type FestivalArtist = {
57
+ export type FestivalArtist = {
60
58
  id: string;
61
59
  name: string;
62
60
  image: string;
@@ -64,7 +62,7 @@ type FestivalArtist = {
64
62
  role: FestivalArtistRole;
65
63
  };
66
64
 
67
- type FestivalArtistRole =
65
+ export type FestivalArtistRole =
68
66
  | "dj"
69
67
  | "dancer"
70
68
  | "mc"
@@ -72,7 +70,7 @@ type FestivalArtistRole =
72
70
  | "organizer"
73
71
  | "media";
74
72
 
75
- type Region =
73
+ export type Region =
76
74
  | "Nordics"
77
75
  | "Baltics"
78
76
  | "Western Europe"
@@ -0,0 +1,2 @@
1
+ export * from "./festival";
2
+ export * from "./user";
@@ -0,0 +1,11 @@
1
+ // Re-export all types from individual files
2
+ export * from "./event";
3
+ export * from "./ticket";
4
+ export * from "./city";
5
+ export * from "./organizer";
6
+ export * from "./user";
7
+ export * from "./other";
8
+ export * from "./analytics";
9
+
10
+ // Re-export from subdirectories
11
+ export * from "./festivals";
@@ -0,0 +1,116 @@
1
+ import { Timestamp } from "@react-native-firebase/firestore";
2
+ import dayjs from "dayjs";
3
+ import relativeTime from "dayjs/plugin/relativeTime";
4
+
5
+ // Register the relativeTime plugin
6
+ dayjs.extend(relativeTime);
7
+
8
+ /**
9
+ * Converts a Firestore Timestamp to a JavaScript Date object
10
+ * @param timestamp Firestore Timestamp or null/undefined
11
+ * @returns JavaScript Date object or null if input is null/undefined
12
+ */
13
+ export const timestampToDate = (
14
+ timestamp: Timestamp | null | undefined
15
+ ): Date | null => {
16
+ if (!timestamp) return null;
17
+ return new Date(timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000);
18
+ };
19
+
20
+ /**
21
+ * Converts a JavaScript Date to a Firestore Timestamp
22
+ * @param date JavaScript Date object or null/undefined
23
+ * @returns Firestore Timestamp or null if input is null/undefined
24
+ */
25
+ export const dateToTimestamp = (
26
+ date: Date | null | undefined
27
+ ): Timestamp | null => {
28
+ if (!date) return null;
29
+ return Timestamp.fromDate(date);
30
+ };
31
+
32
+ /**
33
+ * Formats a Firestore Timestamp to a string using the provided format
34
+ * Uses day.js library - install with: npm install dayjs
35
+ * @param timestamp Firestore Timestamp or null/undefined
36
+ * @param formatStr Format string compatible with day.js format function
37
+ * (see https://day.js.org/docs/en/display/format for format options)
38
+ * @param defaultValue Value to return if timestamp is null/undefined
39
+ * @returns Formatted date string or defaultValue if timestamp is null/undefined
40
+ */
41
+ export const formatTimestamp = (
42
+ timestamp: Timestamp | null | undefined,
43
+ formatStr: string = "MMM D, YYYY",
44
+ defaultValue: string = ""
45
+ ): string => {
46
+ if (!timestamp) return defaultValue;
47
+
48
+ try {
49
+ // Convert timestamp to Date
50
+ const date = new Date(
51
+ timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000
52
+ );
53
+
54
+ // Use dayjs to format the date according to the format string
55
+ return dayjs(date).format(formatStr);
56
+ } catch (error) {
57
+ console.error("Error formatting timestamp:", error);
58
+ return defaultValue;
59
+ }
60
+ };
61
+
62
+ /**
63
+ * Checks if a Firestore Timestamp is before current time
64
+ * @param timestamp Firestore Timestamp to check
65
+ * @returns boolean indicating if timestamp is in the past
66
+ */
67
+ export const isTimestampInPast = (
68
+ timestamp: Timestamp | null | undefined
69
+ ): boolean => {
70
+ if (!timestamp) return false;
71
+
72
+ // Convert timestamp to milliseconds manually
73
+ const timestampMillis =
74
+ timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000;
75
+ return timestampMillis < Date.now();
76
+ };
77
+
78
+ /**
79
+ * Checks if a Firestore Timestamp is after current time
80
+ * @param timestamp Firestore Timestamp to check
81
+ * @returns boolean indicating if timestamp is in the future
82
+ */
83
+ export const isTimestampInFuture = (
84
+ timestamp: Timestamp | null | undefined
85
+ ): boolean => {
86
+ if (!timestamp) return false;
87
+
88
+ // Convert timestamp to milliseconds manually
89
+ const timestampMillis =
90
+ timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000;
91
+ return timestampMillis > Date.now();
92
+ };
93
+
94
+ /**
95
+ * Gets the relative time between now and a Firestore Timestamp (e.g. "2 hours ago", "in 3 days")
96
+ * Uses day.js with relativeTime plugin for localized relative time formatting
97
+ * @param timestamp Firestore Timestamp
98
+ * @returns String representation of relative time
99
+ */
100
+ export const getRelativeTime = (
101
+ timestamp: Timestamp | null | undefined
102
+ ): string => {
103
+ if (!timestamp) return "";
104
+
105
+ try {
106
+ // Convert timestamp to milliseconds manually
107
+ const timestampMillis =
108
+ timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000;
109
+
110
+ // Use dayjs to get relative time
111
+ return dayjs(timestampMillis).fromNow();
112
+ } catch (error) {
113
+ console.error("Error generating relative time:", error);
114
+ return "";
115
+ }
116
+ };
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes