react-achievements 2.0.5 → 2.1.1

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 CHANGED
@@ -43,6 +43,7 @@ const initialState = {
43
43
  experience: 0,
44
44
  monstersDefeated: 0,
45
45
  questsCompleted: 0,
46
+ previouslyAwardedAchievements: ['first_step'], // Optional: Load previously awarded achievements
46
47
  // Add any other initial metrics here
47
48
  };
48
49
 
@@ -51,7 +52,7 @@ function App() {
51
52
  <Provider store={store}>
52
53
  <AchievementProvider
53
54
  config={achievementConfig} // Required: your achievement configuration
54
- initialState={initialState} // Required: initial game metrics. This can be loaded from your server
55
+ initialState={initialState} // Required: initial game metrics and optionally previously awarded achievements. This can be loaded from your server
55
56
  storageKey="my-game-achievements" // Optional: customize local storage key
56
57
  badgesButtonPosition="top-right" // Optional: customize badges button position
57
58
  // Optional: add custom styles and icons here
@@ -231,6 +232,7 @@ export default Game;
231
232
  - Achievement Gallery: Players can view all their unlocked achievements, encouraging completionism.
232
233
  - Confetti Effect: A celebratory confetti effect is displayed when an achievement is unlocked, adding to the excitement.
233
234
  - Local Storage: Achievements are stored locally on the device.
235
+ - **Loading Previous Awards:** The AchievementProvider accepts an optional previouslyAwardedAchievements array in its initialState prop, allowing you to load achievements that the user has already earned.
234
236
  - **Programmatic Reset:** Includes a `resetStorage` function accessible via the `useAchievementContext` hook to easily reset all achievement data.
235
237
 
236
238
  <h2 align="center">🔧 API</h2>
@@ -240,7 +242,7 @@ export default Game;
240
242
  #### Props:
241
243
 
242
244
  - `config`: An object defining your metrics and achievements.
243
- - `initialState`: The initial state of your metrics.
245
+ - `initialState`: The initial state of your metrics. Can also include an optional previouslyAwardedAchievements array of achievement IDs.
244
246
  - `storageKey` (optional): A string to use as the key for localStorage. Default: 'react-achievements'
245
247
  - `badgesButtonPosition` (optional): Position of the badges button. Default: 'top-right'
246
248
  - `styles` (optional): Custom styles for the achievement components.
@@ -253,6 +255,56 @@ export default Game;
253
255
  - `unlockedAchievements`: Array of unlocked achievement IDs. (Note: Access the actual Redux state using `useSelector`).
254
256
  - `resetStorage`: Function to clear all achievement data from local storage and reset the Redux state.
255
257
 
258
+ <h3 align="center">🪝 useAchievementState Hook</h3>
259
+ <h4 align="center">Returns an object containing the current achievement state, useful for saving to a server or other persistent storage.
260
+ </h4>
261
+
262
+
263
+ #### Returns an object with:
264
+
265
+ - `metrics`: The current achievement metrics object.
266
+ - `previouslyAwardedAchievements`: An array of achievement IDs that have been previously awarded to the user.
267
+
268
+ **Example Usage:**
269
+
270
+ ```jsx
271
+ import React from 'react';
272
+ import { useAchievementState } from 'react-achievements';
273
+
274
+ const SyncAchievementsButton = () => {
275
+ const { metrics, previouslyAwardedAchievements } = useAchievementState();
276
+
277
+ const handleSaveToServer = async () => {
278
+ const achievementData = {
279
+ metrics,
280
+ previouslyAwardedAchievements,
281
+ };
282
+ try {
283
+ const response = await fetch('/api/save-achievements', {
284
+ method: 'POST',
285
+ headers: {
286
+ 'Content-Type': 'application/json',
287
+ },
288
+ body: JSON.stringify(achievementData),
289
+ });
290
+ if (response.ok) {
291
+ console.log('Achievement data saved successfully!');
292
+ } else {
293
+ console.error('Failed to save achievement data.');
294
+ }
295
+ } catch (error) {
296
+ console.error('Error saving achievement data:', error);
297
+ }
298
+ };
299
+
300
+ return (
301
+ <button onClick={handleSaveToServer}>Save Achievements to Server</button>
302
+ );
303
+ };
304
+
305
+ export default SyncAchievementsButton;
306
+ ```
307
+
256
308
  <h2 align="center">🎨 Customization</h2>
257
309
 
258
310
  React-Achievements allows for extensive customization of its appearance. You can override the default styles by passing a `styles` prop to the `AchievementProvider`:
@@ -412,6 +464,53 @@ The achievements and metrics are managed by Redux and persisted in local storage
412
464
  }
413
465
  ```
414
466
 
467
+ <h2 align="center">💾 Saving and Loading Progress</h2>
468
+
469
+ <h4 align="center">To persist user achievement progress across sessions or devices, you'll typically want to save the `metrics` and `previouslyAwardedAchievements` from your Redux store to your server. You can use the `useAchievementState` hook to access this data and trigger the save operation, for example, when the user logs out:
470
+ </h4>
471
+
472
+ ```jsx
473
+ import React from 'react';
474
+ import { useAchievementState } from 'react-achievements/hooks/useAchievementState';
475
+
476
+ const LogoutButtonWithSave = ({ onLogout }) => {
477
+ const { metrics, previouslyAwardedAchievements } = useAchievementState();
478
+
479
+ const handleLogoutAndSave = async () => {
480
+ const achievementData = {
481
+ metrics,
482
+ previouslyAwardedAchievements,
483
+ };
484
+ try {
485
+ const response = await fetch('/api/save-achievements', {
486
+ method: 'POST',
487
+ headers: {
488
+ 'Content-Type': 'application/json',
489
+ // Include any necessary authentication headers
490
+ },
491
+ body: JSON.stringify(achievementData),
492
+ });
493
+ if (response.ok) {
494
+ console.log('Achievement data saved successfully before logout!');
495
+ } else {
496
+ console.error('Failed to save achievement data before logout.');
497
+ }
498
+ } catch (error) {
499
+ console.error('Error saving achievement data:', error);
500
+ } finally {
501
+ // Proceed with the logout action regardless of save success
502
+ onLogout();
503
+ }
504
+ };
505
+
506
+ return (
507
+ <button onClick={handleLogoutAndSave}>Logout</button>
508
+ );
509
+ };
510
+
511
+ export default LogoutButtonWithSave;
512
+ ```
513
+
415
514
  <h2 align="center">🏆Available Icons🏆</h2>
416
515
 
417
516
  ```
@@ -2,7 +2,7 @@ export declare const useAchievement: () => {
2
2
  metrics: import("..").AchievementMetrics;
3
3
  unlockedAchievements: string[];
4
4
  notifications: import("..").AchievementDetails[];
5
- config: import("..").AchievementConfiguration;
5
+ config: import("../types").SerializedAchievementConfiguration;
6
6
  updateMetrics: (newMetrics: import("..").AchievementMetrics | ((prevMetrics: import("..").AchievementMetrics) => import("..").AchievementMetrics)) => void;
7
7
  resetStorage: () => void;
8
8
  };
@@ -0,0 +1,4 @@
1
+ export declare const useAchievementState: () => {
2
+ metrics: import("..").AchievementMetrics;
3
+ previouslyAwardedAchievements: string[];
4
+ };