react-achievements 1.0.7 → 1.0.9
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/README.md +5 -5
- package/dist/context/AchievementContext.d.ts +2 -2
- package/dist/index.cjs.js +8 -3
- package/dist/index.esm.js +8 -3
- package/dist/types.d.ts +2 -1
- package/package.json +1 -1
- package/public/badges/icon1.svg +1 -0
- package/src/components/BadgesModal.tsx +0 -1
- package/src/context/AchievementContext.tsx +12 -6
- package/src/types.ts +3 -1
package/README.md
CHANGED
|
@@ -62,12 +62,12 @@ const achievementConfig = {
|
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
|
-
check: (value) =>
|
|
65
|
+
check: (value) => values.reduce((sum, val) => sum + (typeof val === 'number' ? val : 0), 0) >= 100,
|
|
66
66
|
data: {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
id: 'thousand_dollars',
|
|
68
|
+
title: 'Big Spender',
|
|
69
|
+
description: 'Spent a total of $1000',
|
|
70
|
+
icon: '/path/to/icon.png'
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
|
-
import { Metrics, AchievementConfig } from '../types';
|
|
2
|
+
import { Metrics, AchievementConfig, MetricValue } from '../types';
|
|
3
3
|
interface AchievementContextProps {
|
|
4
4
|
metrics: Metrics;
|
|
5
5
|
setMetrics: (metrics: Metrics | ((prevMetrics: Metrics) => Metrics)) => void;
|
|
@@ -10,7 +10,7 @@ interface AchievementContextProps {
|
|
|
10
10
|
interface AchievementProviderProps {
|
|
11
11
|
children: ReactNode;
|
|
12
12
|
config: AchievementConfig;
|
|
13
|
-
initialState?: Record<string,
|
|
13
|
+
initialState?: Record<string, MetricValue>;
|
|
14
14
|
storageKey?: string;
|
|
15
15
|
badgesButtonPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
16
16
|
}
|
package/dist/index.cjs.js
CHANGED
|
@@ -68,8 +68,7 @@ const BadgesModal = ({ show, achievements, onClose }) => {
|
|
|
68
68
|
React.createElement("h2", { id: "badges-title" }, "Your Achievements"),
|
|
69
69
|
React.createElement("div", { style: { display: 'flex', flexWrap: 'wrap', justifyContent: 'center' } }, achievements.map(achievement => (React.createElement("div", { key: achievement.id, style: { margin: '10px', textAlign: 'center' } },
|
|
70
70
|
React.createElement("img", { src: achievement.icon, alt: achievement.title, style: { width: '50px', height: '50px' } }),
|
|
71
|
-
React.createElement("h4", null, achievement.title),
|
|
72
|
-
React.createElement("p", null, achievement.description))))),
|
|
71
|
+
React.createElement("h4", null, achievement.title))))),
|
|
73
72
|
React.createElement("button", { onClick: onClose, style: { marginTop: '20px' } }, "Close"))));
|
|
74
73
|
};
|
|
75
74
|
var BadgesModal$1 = React.memo(BadgesModal);
|
|
@@ -191,9 +190,15 @@ const AchievementProvider = ({ children, config, initialState = {}, storageKey =
|
|
|
191
190
|
if (key in state) {
|
|
192
191
|
acc[key] = state[key];
|
|
193
192
|
}
|
|
193
|
+
else {
|
|
194
|
+
acc[key] = [];
|
|
195
|
+
}
|
|
194
196
|
return acc;
|
|
195
197
|
}, {});
|
|
196
198
|
};
|
|
199
|
+
const getAchievements = () => {
|
|
200
|
+
return Object.values(config).flatMap(conditions => conditions.filter(c => achievedAchievements.includes(c.data.id)).map(c => c.data));
|
|
201
|
+
};
|
|
197
202
|
const [metrics, setMetrics] = React.useState(() => {
|
|
198
203
|
const savedMetrics = localStorage.getItem(`${storageKey}-metrics`);
|
|
199
204
|
if (savedMetrics) {
|
|
@@ -253,7 +258,7 @@ const AchievementProvider = ({ children, config, initialState = {}, storageKey =
|
|
|
253
258
|
setNewAchievement(null);
|
|
254
259
|
setShowConfetti(false);
|
|
255
260
|
} }),
|
|
256
|
-
React.createElement(BadgesModal$1, { show: showBadges, achievements:
|
|
261
|
+
React.createElement(BadgesModal$1, { show: showBadges, achievements: getAchievements(), onClose: () => setShowBadges(false) }),
|
|
257
262
|
React.createElement(BadgesButton$1, { onClick: showBadgesModal, position: badgesButtonPosition }),
|
|
258
263
|
React.createElement(ConfettiWrapper, { show: showConfetti })));
|
|
259
264
|
};
|
package/dist/index.esm.js
CHANGED
|
@@ -66,8 +66,7 @@ const BadgesModal = ({ show, achievements, onClose }) => {
|
|
|
66
66
|
React.createElement("h2", { id: "badges-title" }, "Your Achievements"),
|
|
67
67
|
React.createElement("div", { style: { display: 'flex', flexWrap: 'wrap', justifyContent: 'center' } }, achievements.map(achievement => (React.createElement("div", { key: achievement.id, style: { margin: '10px', textAlign: 'center' } },
|
|
68
68
|
React.createElement("img", { src: achievement.icon, alt: achievement.title, style: { width: '50px', height: '50px' } }),
|
|
69
|
-
React.createElement("h4", null, achievement.title),
|
|
70
|
-
React.createElement("p", null, achievement.description))))),
|
|
69
|
+
React.createElement("h4", null, achievement.title))))),
|
|
71
70
|
React.createElement("button", { onClick: onClose, style: { marginTop: '20px' } }, "Close"))));
|
|
72
71
|
};
|
|
73
72
|
var BadgesModal$1 = React.memo(BadgesModal);
|
|
@@ -189,9 +188,15 @@ const AchievementProvider = ({ children, config, initialState = {}, storageKey =
|
|
|
189
188
|
if (key in state) {
|
|
190
189
|
acc[key] = state[key];
|
|
191
190
|
}
|
|
191
|
+
else {
|
|
192
|
+
acc[key] = [];
|
|
193
|
+
}
|
|
192
194
|
return acc;
|
|
193
195
|
}, {});
|
|
194
196
|
};
|
|
197
|
+
const getAchievements = () => {
|
|
198
|
+
return Object.values(config).flatMap(conditions => conditions.filter(c => achievedAchievements.includes(c.data.id)).map(c => c.data));
|
|
199
|
+
};
|
|
195
200
|
const [metrics, setMetrics] = useState(() => {
|
|
196
201
|
const savedMetrics = localStorage.getItem(`${storageKey}-metrics`);
|
|
197
202
|
if (savedMetrics) {
|
|
@@ -251,7 +256,7 @@ const AchievementProvider = ({ children, config, initialState = {}, storageKey =
|
|
|
251
256
|
setNewAchievement(null);
|
|
252
257
|
setShowConfetti(false);
|
|
253
258
|
} }),
|
|
254
|
-
React.createElement(BadgesModal$1, { show: showBadges, achievements:
|
|
259
|
+
React.createElement(BadgesModal$1, { show: showBadges, achievements: getAchievements(), onClose: () => setShowBadges(false) }),
|
|
255
260
|
React.createElement(BadgesButton$1, { onClick: showBadgesModal, position: badgesButtonPosition }),
|
|
256
261
|
React.createElement(ConfettiWrapper, { show: showConfetti })));
|
|
257
262
|
};
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M560-440q-50 0-85-35t-35-85q0-50 35-85t85-35q50 0 85 35t35 85q0 50-35 85t-85 35ZM280-320q-33 0-56.5-23.5T200-400v-320q0-33 23.5-56.5T280-800h560q33 0 56.5 23.5T920-720v320q0 33-23.5 56.5T840-320H280Zm80-80h400q0-33 23.5-56.5T840-480v-160q-33 0-56.5-23.5T760-720H360q0 33-23.5 56.5T280-640v160q33 0 56.5 23.5T360-400Zm440 240H120q-33 0-56.5-23.5T40-240v-440h80v440h680v80ZM280-400v-320 320Z"/></svg>
|
|
@@ -45,7 +45,6 @@ const BadgesModal: React.FC<BadgesModalProps> = ({ show, achievements, onClose }
|
|
|
45
45
|
<div key={achievement.id} style={{ margin: '10px', textAlign: 'center' }}>
|
|
46
46
|
<img src={achievement.icon} alt={achievement.title} style={{ width: '50px', height: '50px' }} />
|
|
47
47
|
<h4>{achievement.title}</h4>
|
|
48
|
-
<p>{achievement.description}</p>
|
|
49
48
|
</div>
|
|
50
49
|
))}
|
|
51
50
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';
|
|
2
|
-
import { Metrics, AchievementConfig, AchievementData } from '../types';
|
|
2
|
+
import { Metrics, AchievementConfig, AchievementData, MetricValue } from '../types';
|
|
3
3
|
import AchievementModal from '../components/AchievementModal';
|
|
4
4
|
import BadgesModal from '../components/BadgesModal';
|
|
5
5
|
import BadgesButton from '../components/BadgesButton';
|
|
@@ -16,7 +16,7 @@ interface AchievementContextProps {
|
|
|
16
16
|
interface AchievementProviderProps {
|
|
17
17
|
children: ReactNode;
|
|
18
18
|
config: AchievementConfig;
|
|
19
|
-
initialState?: Record<string,
|
|
19
|
+
initialState?: Record<string, MetricValue>;
|
|
20
20
|
storageKey?: string;
|
|
21
21
|
badgesButtonPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
22
22
|
}
|
|
@@ -30,15 +30,23 @@ export const AchievementProvider: React.FC<AchievementProviderProps> = ({
|
|
|
30
30
|
storageKey = 'react-achievements',
|
|
31
31
|
badgesButtonPosition = 'top-right'
|
|
32
32
|
}) => {
|
|
33
|
-
const extractMetrics = (state: Record<string,
|
|
33
|
+
const extractMetrics = (state: Record<string, MetricValue>): Metrics => {
|
|
34
34
|
return Object.keys(config).reduce((acc, key) => {
|
|
35
35
|
if (key in state) {
|
|
36
36
|
acc[key] = state[key];
|
|
37
|
+
} else {
|
|
38
|
+
acc[key] = [];
|
|
37
39
|
}
|
|
38
40
|
return acc;
|
|
39
41
|
}, {} as Metrics);
|
|
40
42
|
};
|
|
41
43
|
|
|
44
|
+
const getAchievements = () =>{
|
|
45
|
+
return Object.values(config).flatMap(conditions =>
|
|
46
|
+
conditions.filter(c => achievedAchievements.includes(c.data.id)).map(c => c.data)
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
42
50
|
const [metrics, setMetrics] = useState<Metrics>(() => {
|
|
43
51
|
const savedMetrics = localStorage.getItem(`${storageKey}-metrics`);
|
|
44
52
|
if (savedMetrics) {
|
|
@@ -115,9 +123,7 @@ export const AchievementProvider: React.FC<AchievementProviderProps> = ({
|
|
|
115
123
|
/>
|
|
116
124
|
<BadgesModal
|
|
117
125
|
show={showBadges}
|
|
118
|
-
achievements={
|
|
119
|
-
conditions.filter(c => achievedAchievements.includes(c.data.id)).map(c => c.data)
|
|
120
|
-
)}
|
|
126
|
+
achievements={getAchievements()}
|
|
121
127
|
onClose={() => setShowBadges(false)}
|
|
122
128
|
/>
|
|
123
129
|
<BadgesButton onClick={showBadgesModal} position={badgesButtonPosition} />
|