@umituz/react-native-gamification 1.2.0 → 1.3.0

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.
@@ -1,101 +0,0 @@
1
- /**
2
- * Leaderboard Entity
3
- *
4
- * Represents leaderboard entries in the gamification system
5
- */
6
-
7
- export interface LeaderboardEntry {
8
- id: string;
9
- userId: string;
10
- leaderboardId: string; // Leaderboard identifier (e.g., "global", "weekly", "monthly")
11
- rank: number; // Current rank (1-based)
12
- score: number; // Score for ranking
13
- metric: string; // Metric used for ranking (e.g., "points", "experience", "streak")
14
- displayName?: string; // User's display name
15
- avatar?: string; // User's avatar URL
16
- metadata?: Record<string, any>;
17
- period?: "daily" | "weekly" | "monthly" | "all-time"; // Time period for leaderboard
18
- periodStart?: string; // Start date of the period
19
- periodEnd?: string; // End date of the period
20
- createdDate: string;
21
- updatedDate: string;
22
- }
23
-
24
- export interface Leaderboard {
25
- id: string;
26
- name: string;
27
- description?: string;
28
- metric: string; // Metric used for ranking
29
- period?: "daily" | "weekly" | "monthly" | "all-time";
30
- periodStart?: string;
31
- periodEnd?: string;
32
- entries: LeaderboardEntry[];
33
- totalParticipants: number;
34
- lastUpdated: string;
35
- }
36
-
37
- export interface LeaderboardRanking {
38
- userId: string;
39
- rank: number;
40
- score: number;
41
- percentile: number; // Percentile rank (0-100)
42
- aboveUsers: number; // Number of users above
43
- belowUsers: number; // Number of users below
44
- }
45
-
46
- export type LeaderboardCategory = 'points' | 'achievements' | 'streaks' | 'activity';
47
-
48
- /**
49
- * Factory function to create leaderboard entry
50
- */
51
- export function createLeaderboardEntry(
52
- props: Omit<LeaderboardEntry, 'id' | 'createdDate' | 'updatedDate' | 'change'> & { previousRank?: number }
53
- ): LeaderboardEntry {
54
- const now = new Date().toISOString();
55
- const change = props.previousRank ? props.previousRank - props.rank : 0;
56
-
57
- return {
58
- ...props,
59
- id: `entry-${Date.now()}-${Math.random().toString(36).substring(7)}`,
60
- createdDate: now,
61
- updatedDate: now,
62
- metadata: {
63
- ...props.metadata,
64
- change,
65
- },
66
- };
67
- }
68
-
69
- /**
70
- * Calculate rank change indicator
71
- */
72
- export function getRankChangeIndicator(change: number): '↑' | '↓' | '=' {
73
- if (change > 0) return '↑'; // Improved (moved up)
74
- if (change < 0) return '↓'; // Declined (moved down)
75
- return '='; // No change
76
- }
77
-
78
- /**
79
- * Get top N entries from leaderboard
80
- */
81
- export function getTopEntries(
82
- leaderboard: Leaderboard,
83
- limit: number = 10
84
- ): LeaderboardEntry[] {
85
- return leaderboard.entries
86
- .sort((a, b) => a.rank - b.rank)
87
- .slice(0, limit);
88
- }
89
-
90
- /**
91
- * Find user's position in leaderboard
92
- */
93
- export function findUserRank(
94
- leaderboard: Leaderboard,
95
- userId: string
96
- ): LeaderboardEntry | null {
97
- return leaderboard.entries.find((entry) => entry.userId === userId) || null;
98
- }
99
-
100
-
101
-
@@ -1,40 +0,0 @@
1
- /**
2
- * Level Entity
3
- *
4
- * Represents user levels in the gamification system
5
- */
6
-
7
- export interface Level {
8
- id: string;
9
- userId: string;
10
- currentLevel: number;
11
- currentExperience: number; // Current XP in current level
12
- totalExperience: number; // Total XP accumulated
13
- experienceToNextLevel: number; // XP needed for next level
14
- levelProgress: number; // Percentage progress in current level (0-100)
15
- metadata?: Record<string, any>;
16
- createdDate: string;
17
- updatedDate: string;
18
- }
19
-
20
- export interface LevelDefinition {
21
- level: number;
22
- experienceRequired: number; // Total XP required to reach this level
23
- title?: string;
24
- description?: string;
25
- rewards?: string[]; // Reward IDs or types
26
- metadata?: Record<string, any>;
27
- }
28
-
29
- export interface LevelProgress {
30
- userId: string;
31
- currentLevel: number;
32
- currentExperience: number;
33
- totalExperience: number;
34
- experienceToNextLevel: number;
35
- levelProgress: number;
36
- canLevelUp: boolean;
37
- }
38
-
39
-
40
-
@@ -1,40 +0,0 @@
1
- /**
2
- * Point Entity
3
- *
4
- * Represents points in the gamification system
5
- */
6
-
7
- export interface Point {
8
- id: string;
9
- userId: string;
10
- amount: number;
11
- source: string; // Source of points (e.g., "achievement", "action", "reward")
12
- sourceId?: string; // ID of the source (e.g., achievement ID)
13
- category?: string; // Category for grouping points
14
- description?: string;
15
- metadata?: Record<string, any>;
16
- createdDate: string;
17
- }
18
-
19
- export interface PointBalance {
20
- userId: string;
21
- total: number;
22
- byCategory: Record<string, number>; // Points grouped by category
23
- lastUpdated: string;
24
- }
25
-
26
- export interface PointTransaction {
27
- id: string;
28
- userId: string;
29
- amount: number; // Can be negative for deductions
30
- source: string;
31
- sourceId?: string;
32
- category?: string;
33
- description?: string;
34
- balance: number; // Balance after this transaction
35
- metadata?: Record<string, any>;
36
- createdDate: string;
37
- }
38
-
39
-
40
-
@@ -1,43 +0,0 @@
1
- /**
2
- * Progress Entity
3
- *
4
- * Represents user progress tracking in the gamification system
5
- */
6
-
7
- export interface Progress {
8
- id: string;
9
- userId: string;
10
- metric: string; // Metric identifier (e.g., "goals_completed", "sessions_attended")
11
- currentValue: number; // Current value
12
- targetValue?: number; // Target value (optional)
13
- progress: number; // Percentage progress (0-100)
14
- unit?: string; // Unit of measurement (e.g., "times", "hours", "days")
15
- category?: string; // Category for grouping
16
- period?: "daily" | "weekly" | "monthly" | "all-time"; // Time period
17
- periodStart?: string; // Start date of the period
18
- periodEnd?: string; // End date of the period
19
- metadata?: Record<string, any>;
20
- createdDate: string;
21
- updatedDate: string;
22
- }
23
-
24
- export interface ProgressUpdate {
25
- userId: string;
26
- metric: string;
27
- increment: number; // Amount to increment
28
- category?: string;
29
- period?: "daily" | "weekly" | "monthly" | "all-time";
30
- metadata?: Record<string, any>;
31
- }
32
-
33
- export interface ProgressMilestone {
34
- metric: string;
35
- value: number;
36
- title: string;
37
- description?: string;
38
- reward?: string; // Reward ID or type
39
- metadata?: Record<string, any>;
40
- }
41
-
42
-
43
-
@@ -1,131 +0,0 @@
1
- /**
2
- * Reward Entity
3
- *
4
- * Represents rewards in the gamification system
5
- */
6
-
7
- import type { PointTransaction } from './Point';
8
-
9
- export interface Reward {
10
- id: string;
11
- userId: string;
12
- type: string; // Reward type (e.g., "badge", "unlock", "discount", "item")
13
- title: string;
14
- description?: string;
15
- icon?: string;
16
- category?: string;
17
- pointsCost?: number; // Points required to claim
18
- levelRequired?: number; // Level required to claim
19
- unlocked: boolean;
20
- unlockedDate?: string;
21
- claimed: boolean;
22
- claimedDate?: string;
23
- expiresAt?: string; // Expiration date for time-limited rewards
24
- metadata?: Record<string, any>;
25
- createdDate: string;
26
- updatedDate: string;
27
- }
28
-
29
- export interface RewardDefinition {
30
- type: string;
31
- title: string;
32
- description?: string;
33
- icon?: string;
34
- category?: string;
35
- pointsCost?: number;
36
- levelRequired?: number;
37
- rarity?: "common" | "rare" | "epic" | "legendary";
38
- expiresAt?: string;
39
- metadata?: Record<string, any>;
40
- }
41
-
42
- export interface RewardClaim {
43
- id: string;
44
- userId: string;
45
- rewardId: string;
46
- pointsSpent?: number;
47
- claimedDate: string;
48
- metadata?: Record<string, any>;
49
- }
50
-
51
- export type RewardRarity = 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary';
52
-
53
- /**
54
- * Factory function to create reward
55
- */
56
- export function createReward(
57
- props: Omit<Reward, 'id' | 'unlocked' | 'claimed' | 'createdDate' | 'updatedDate'>
58
- ): Reward {
59
- const now = new Date().toISOString();
60
- return {
61
- ...props,
62
- id: `reward-${Date.now()}-${Math.random().toString(36).substring(7)}`,
63
- unlocked: false,
64
- claimed: false,
65
- createdDate: now,
66
- updatedDate: now,
67
- };
68
- }
69
-
70
- /**
71
- * Factory function to create points transaction
72
- */
73
- export function createPointsTransaction(
74
- userId: string,
75
- amount: number,
76
- type: 'earn' | 'spend' | 'bonus',
77
- source: string,
78
- description: string
79
- ): PointTransaction {
80
- const now = new Date().toISOString();
81
- return {
82
- id: `transaction-${Date.now()}-${Math.random().toString(36).substring(7)}`,
83
- userId,
84
- amount: type === 'spend' ? -Math.abs(amount) : Math.abs(amount),
85
- source,
86
- description,
87
- balance: 0, // Will be calculated by repository
88
- createdDate: now,
89
- };
90
- }
91
-
92
- /**
93
- * Calculate user level from total experience/points
94
- */
95
- export function calculateLevel(totalPoints: number): number {
96
- // Simple level formula: level = floor(sqrt(points / 100))
97
- return Math.floor(Math.sqrt(totalPoints / 100));
98
- }
99
-
100
- /**
101
- * Calculate points needed for next level
102
- */
103
- export function calculateNextLevelPoints(currentLevel: number): number {
104
- const nextLevel = currentLevel + 1;
105
- return Math.pow(nextLevel, 2) * 100;
106
- }
107
-
108
- /**
109
- * Check if reward is expired
110
- */
111
- export function isRewardExpired(reward: Reward): boolean {
112
- if (!reward.expiresAt) return false;
113
- return new Date() > new Date(reward.expiresAt);
114
- }
115
-
116
- /**
117
- * Get points value for rarity
118
- */
119
- export function getPointsForRarity(rarity: RewardRarity): number {
120
- const pointsMap: Record<RewardRarity, number> = {
121
- common: 50,
122
- uncommon: 100,
123
- rare: 250,
124
- epic: 500,
125
- legendary: 1000,
126
- };
127
- return pointsMap[rarity];
128
- }
129
-
130
-
131
-
@@ -1,154 +0,0 @@
1
- /**
2
- * Streak Entity
3
- *
4
- * Represents user streaks in the gamification system
5
- */
6
-
7
- export interface Streak {
8
- id: string;
9
- userId: string;
10
- type: string; // Streak type (e.g., "daily_login", "daily_goal", "weekly_workout")
11
- currentStreak: number; // Current consecutive days/actions
12
- longestStreak: number; // Longest streak ever achieved
13
- lastActivityDate: string; // Last date when streak was maintained
14
- isActive: boolean; // Whether streak is currently active
15
- metadata?: Record<string, any>;
16
- createdDate: string;
17
- updatedDate: string;
18
- }
19
-
20
- export interface StreakDefinition {
21
- type: string;
22
- name: string;
23
- description?: string;
24
- resetOnMiss: boolean; // Whether streak resets if missed
25
- timezone?: string; // Timezone for daily streaks
26
- metadata?: Record<string, any>;
27
- }
28
-
29
- export interface StreakProgress {
30
- userId: string;
31
- type: string;
32
- currentStreak: number;
33
- longestStreak: number;
34
- isActive: boolean;
35
- daysUntilMilestone?: number; // Days until next milestone (7, 30, 100, etc.)
36
- nextMilestone?: number; // Next milestone value
37
- }
38
-
39
- export interface StreakMilestone {
40
- days: number;
41
- name: string;
42
- reward: number; // Points awarded
43
- achieved: boolean;
44
- }
45
-
46
- /**
47
- * Factory function to create streak entity
48
- */
49
- export function createStreakEntity(userId: string, type: string): Streak {
50
- const now = new Date().toISOString();
51
- return {
52
- id: `streak-${Date.now()}-${Math.random().toString(36).substring(7)}`,
53
- userId,
54
- type,
55
- currentStreak: 0,
56
- longestStreak: 0,
57
- lastActivityDate: now,
58
- isActive: false,
59
- createdDate: now,
60
- updatedDate: now,
61
- };
62
- }
63
-
64
- /**
65
- * Check if streak should continue (activity within last 24 hours)
66
- */
67
- export function isStreakActive(streak: Streak): boolean {
68
- const now = new Date();
69
- const lastActivity = new Date(streak.lastActivityDate);
70
- const hoursSinceLastActivity = (now.getTime() - lastActivity.getTime()) / (1000 * 60 * 60);
71
-
72
- return hoursSinceLastActivity <= 24;
73
- }
74
-
75
- /**
76
- * Check if streak is broken (no activity for more than 48 hours)
77
- */
78
- export function isStreakBroken(streak: Streak): boolean {
79
- const now = new Date();
80
- const lastActivity = new Date(streak.lastActivityDate);
81
- const hoursSinceLastActivity = (now.getTime() - lastActivity.getTime()) / (1000 * 60 * 60);
82
-
83
- return hoursSinceLastActivity > 48;
84
- }
85
-
86
- /**
87
- * Update streak with new activity
88
- */
89
- export function updateStreakWithActivity(streak: Streak): Streak {
90
- const now = new Date().toISOString();
91
-
92
- // Check if streak is broken
93
- if (isStreakBroken(streak)) {
94
- return {
95
- ...streak,
96
- currentStreak: 1,
97
- longestStreak: Math.max(1, streak.longestStreak),
98
- lastActivityDate: now,
99
- isActive: true,
100
- updatedDate: now,
101
- };
102
- }
103
-
104
- // Continue streak
105
- const newStreak = streak.currentStreak + 1;
106
- const newLongestStreak = Math.max(newStreak, streak.longestStreak);
107
-
108
- return {
109
- ...streak,
110
- currentStreak: newStreak,
111
- longestStreak: newLongestStreak,
112
- lastActivityDate: now,
113
- isActive: true,
114
- updatedDate: now,
115
- };
116
- }
117
-
118
- /**
119
- * Get streak milestones
120
- */
121
- export function getStreakMilestones(currentStreak: number): StreakMilestone[] {
122
- const milestones: StreakMilestone[] = [
123
- { days: 7, name: 'Week Warrior', reward: 50, achieved: currentStreak >= 7 },
124
- { days: 14, name: 'Fortnight Fighter', reward: 100, achieved: currentStreak >= 14 },
125
- { days: 30, name: 'Monthly Master', reward: 250, achieved: currentStreak >= 30 },
126
- { days: 60, name: 'Consistency Champion', reward: 500, achieved: currentStreak >= 60 },
127
- { days: 100, name: 'Century Star', reward: 1000, achieved: currentStreak >= 100 },
128
- { days: 365, name: 'Yearly Legend', reward: 5000, achieved: currentStreak >= 365 },
129
- ];
130
-
131
- return milestones;
132
- }
133
-
134
- /**
135
- * Get next milestone for motivation
136
- */
137
- export function getNextMilestone(currentStreak: number): StreakMilestone | null {
138
- const milestones = getStreakMilestones(currentStreak);
139
- return milestones.find((m) => !m.achieved) || null;
140
- }
141
-
142
- /**
143
- * Calculate days until streak break
144
- */
145
- export function getDaysUntilStreakBreak(streak: Streak): number {
146
- const now = new Date();
147
- const lastActivity = new Date(streak.lastActivityDate);
148
- const hoursRemaining = 48 - (now.getTime() - lastActivity.getTime()) / (1000 * 60 * 60);
149
-
150
- return Math.max(0, Math.ceil(hoursRemaining / 24));
151
- }
152
-
153
-
154
-