File size: 2,785 Bytes
fca46f5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { useState, useEffect, useCallback } from 'react';

const USER_ID_KEY = 'pcpal_userId';

/**
 * useUser — User profile hook for PC Pal
 *
 * Checks localStorage for an existing userId on mount.
 * If found, loads the profile from the API.
 * Exposes helpers to create a user and complete onboarding.
 *
 * @returns {{ user, isOnboarded, isLoading, createUser, completeOnboarding }}
 */
export function useUser() {
  const [user, setUser] = useState(null);
  const [isOnboarded, setIsOnboarded] = useState(false);
  const [isLoading, setIsLoading] = useState(true);

  // On mount: check localStorage for a saved userId
  useEffect(() => {
    const savedId = localStorage.getItem(USER_ID_KEY);

    if (!savedId) {
      setIsLoading(false);
      return;
    }

    // Fetch the user profile
    fetch(`/api/users/${savedId}`)
      .then((res) => {
        if (!res.ok) {
          // User not found on server — clear stale localStorage entry
          localStorage.removeItem(USER_ID_KEY);
          return null;
        }
        return res.json();
      })
      .then((data) => {
        if (data) {
          setUser(data);
          setIsOnboarded(Boolean(data.is_onboarded ?? data.isOnboarded));
        }
      })
      .catch((err) => {
        console.error('PC Pal: failed to load user profile', err);
        localStorage.removeItem(USER_ID_KEY);
      })
      .finally(() => {
        setIsLoading(false);
      });
  }, []);

  /**
   * Create a new user account.
   * @param {{ name: string, os_type: string, comfort_level: number }} data
   * @returns {Promise<object>} the created user
   */
  const createUser = useCallback(async (data) => {
    const res = await fetch('/api/users', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });

    if (!res.ok) {
      const err = await res.text();
      throw new Error(`Failed to create user: ${err}`);
    }

    const newUser = await res.json();
    localStorage.setItem(USER_ID_KEY, newUser.id);
    setUser(newUser);
    return newUser;
  }, []);

  /**
   * Mark the user as having completed onboarding.
   * @param {string|number} userId
   * @returns {Promise<object>} the updated user
   */
  const completeOnboarding = useCallback(async (userId) => {
    const res = await fetch(`/api/users/${userId}/onboard`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
    });

    if (!res.ok) {
      const err = await res.text();
      throw new Error(`Failed to complete onboarding: ${err}`);
    }

    const updatedUser = await res.json();
    setUser(updatedUser);
    setIsOnboarded(true);
    return updatedUser;
  }, []);

  return { user, isOnboarded, isLoading, createUser, completeOnboarding };
}