update ui design for all pages
This commit is contained in:
@@ -5,6 +5,55 @@ import { recalcProfilePatch } from './krowScore';
|
||||
import { logActivity } from './userTracking';
|
||||
import { evaluateChallenge } from './provingGround';
|
||||
|
||||
/**
|
||||
* The signed-in user, on the `['user']` key the assistant and the 404 page
|
||||
* already read. One cache entry means a profile edit reaches the navbar, the
|
||||
* Profile page and Owliver's greeting without any of them knowing about each
|
||||
* other.
|
||||
*/
|
||||
export function useCurrentUser() {
|
||||
return useQuery({
|
||||
queryKey: ['user'],
|
||||
queryFn: () => base44.auth.me().catch(() => null),
|
||||
staleTime: Infinity,
|
||||
});
|
||||
}
|
||||
|
||||
/** Saves profile fields and refreshes every consumer of `['user']`. */
|
||||
export function useUpdateProfile() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (patch) => base44.auth.updateMe(patch),
|
||||
onSuccess: (user) => {
|
||||
queryClient.setQueryData(['user'], user);
|
||||
queryClient.invalidateQueries({ queryKey: ['user'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Product preferences, stored on the user record.
|
||||
*
|
||||
* Reads fall back to the synchronous accessor so the first render already has
|
||||
* the real values rather than a default that corrects itself a tick later.
|
||||
*/
|
||||
export function usePreferences() {
|
||||
const { data: user } = useCurrentUser();
|
||||
return { ...base44.auth.preferences(), ...(user?.preferences || {}) };
|
||||
}
|
||||
|
||||
/** Writes one or more preferences and refreshes every consumer of `['user']`. */
|
||||
export function useUpdatePreferences() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (patch) => base44.auth.updatePreferences(patch),
|
||||
onSuccess: (user) => {
|
||||
queryClient.setQueryData(['user'], user);
|
||||
queryClient.invalidateQueries({ queryKey: ['user'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useJobPostings() {
|
||||
return useQuery({
|
||||
queryKey: ['jobPostings'],
|
||||
@@ -278,6 +327,38 @@ export function useCourse(id) {
|
||||
return useQuery({ queryKey: ['course', id], queryFn: () => base44.entities.Course.get(id), enabled: !!id });
|
||||
}
|
||||
|
||||
/**
|
||||
* Author a skill in KROW Forge.
|
||||
*
|
||||
* A skill and the challenge that verifies it are one Course record — the entity
|
||||
* already carries the skill (title, category, difficulty, proof_skill), the
|
||||
* training (quiz, estimated_minutes), the proof (challenge.type) and the
|
||||
* evaluation Owliver runs (challenge.rubric). So Forge authoring is a create on
|
||||
* the entity the whole product already reads, not a parallel store.
|
||||
*/
|
||||
export function useCreateCourse() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (data) => base44.entities.Course.create(data),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['courses'] });
|
||||
logActivity('create_skill_training');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** Status changes and edits to an existing skill. */
|
||||
export function useUpdateCourse() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ id, data }) => base44.entities.Course.update(id, data),
|
||||
onSuccess: (_data, variables) => {
|
||||
queryClient.invalidateQueries({ queryKey: ['courses'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['course', variables.id] });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useLearningPaths() {
|
||||
return useQuery({ queryKey: ['learningPaths'], queryFn: () => base44.entities.LearningPath.list('-created_date', 100) });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user