copy base dmenu to dkala
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
import { checkUserExists } from "@/lib/api/auth/user-exists"
|
||||
import { useQueryClient } from "@tanstack/react-query"
|
||||
|
||||
export const useCheckUserExistsLazy = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const run = (phone: string) =>
|
||||
queryClient.fetchQuery({
|
||||
queryKey: ['checkUserExists', phone],
|
||||
queryFn: () => checkUserExists({ phone }),
|
||||
})
|
||||
|
||||
return { run }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
import { useAuthStore } from '@/zustand/authStore'
|
||||
import { login } from '@/lib/api/auth/login'
|
||||
|
||||
export const useLogin = () =>
|
||||
useMutation({
|
||||
mutationFn: login,
|
||||
onSuccess: (data) => {
|
||||
useAuthStore.getState().login(data)
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
import { requestOtp } from "@/lib/api/auth/request-otp"
|
||||
import { useQueryClient } from "@tanstack/react-query"
|
||||
|
||||
export const useOtpRequest = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const run = (phone: string) =>
|
||||
queryClient.fetchQuery({
|
||||
queryKey: ['requestOtp', phone],
|
||||
queryFn: () => requestOtp({ phone }),
|
||||
})
|
||||
|
||||
return { run }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { OtpValidationRequestModel, validateOtp } from "@/lib/api/auth/validate-otp"
|
||||
import { useQueryClient } from "@tanstack/react-query"
|
||||
|
||||
export const useOtpValidation = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const run = (model: OtpValidationRequestModel) =>
|
||||
queryClient.fetchQuery({
|
||||
queryKey: ['requestOtpValidation', model],
|
||||
queryFn: () => validateOtp(model),
|
||||
})
|
||||
|
||||
return { run }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
import { useAuthStore } from '@/zustand/authStore'
|
||||
import { fetchMe } from '@/lib/api/auth/me'
|
||||
|
||||
export const useProfile = () =>
|
||||
useMutation({
|
||||
mutationFn: fetchMe,
|
||||
onSuccess: (data) => {
|
||||
useAuthStore.getState().update(data)
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,15 @@
|
||||
import { refreshToken } from "@/lib/api/auth/refresh-token"
|
||||
import { useAuthStore } from "@/zustand/authStore"
|
||||
import { useMutation } from "@tanstack/react-query"
|
||||
|
||||
export const useOtpRequest = () => {
|
||||
useMutation({
|
||||
mutationFn: refreshToken,
|
||||
onSuccess: (data) => {
|
||||
useAuthStore.getState().setToken(data.accessToken)
|
||||
},
|
||||
onError: () => {
|
||||
useAuthStore.getState().logout();
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import { useAuthStore } from '@/zustand/authStore'
|
||||
import { resetPassword, ResetPasswordRequestModel } from '@/lib/api/auth/reset-password';
|
||||
|
||||
export const useResetPassword = () =>
|
||||
{
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const run = (model: ResetPasswordRequestModel) =>
|
||||
queryClient.fetchQuery({
|
||||
queryKey: ['resetPassword', model],
|
||||
queryFn: () => resetPassword(model),
|
||||
}).then(() => {
|
||||
useAuthStore.getState().logout();
|
||||
}).catch((ex) => {
|
||||
throw ex;
|
||||
})
|
||||
|
||||
return { run }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
import { signup } from '@/lib/api/auth/signup'
|
||||
import { useAuthStore } from '@/zustand/authStore'
|
||||
|
||||
export const useSignup = () =>
|
||||
useMutation({
|
||||
mutationFn: signup,
|
||||
onSuccess: (data) => {
|
||||
useAuthStore.getState().login(data)
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,31 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { usePreferencesStore } from '@/zustand/preferencesStore';
|
||||
|
||||
function usePreference<T>(key: string, initial?: T) {
|
||||
const value = usePreferencesStore((s) => s.items[key]?.value as T);
|
||||
const setValue = usePreferencesStore((s) => s.set);
|
||||
const toggleValue = usePreferencesStore((s) => s.toggle);
|
||||
const [hydrated, setHydrated] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setHydrated(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (hydrated && value === undefined) {
|
||||
setValue(key, initial ?? null);
|
||||
}
|
||||
}, [hydrated, value, key, initial, setValue]);
|
||||
|
||||
const toggle = (e?: React.MouseEvent | null) => {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
toggleValue(key);
|
||||
};
|
||||
|
||||
return { state: value, toggle, set: setValue, hydrated };
|
||||
}
|
||||
|
||||
export default usePreference;
|
||||
@@ -0,0 +1,43 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { hexToOklch, calculateBrightness } from "@/lib/helpers/colorUtils";
|
||||
|
||||
interface UseThemeColorProps {
|
||||
primaryColor?: string | null;
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* هوک برای تغییر دینامیک رنگ primary بر اساس رنگ دریافتی از about
|
||||
*/
|
||||
export function useThemeColor({
|
||||
primaryColor,
|
||||
enabled = true,
|
||||
}: UseThemeColorProps) {
|
||||
useEffect(() => {
|
||||
if (!enabled || !primaryColor) return;
|
||||
|
||||
try {
|
||||
const root = document.documentElement;
|
||||
|
||||
// اگر رنگ hex هست، آن را به oklch تبدیل میکنیم
|
||||
if (primaryColor.startsWith("#")) {
|
||||
const oklchColor = hexToOklch(primaryColor);
|
||||
|
||||
if (oklchColor) {
|
||||
// اعمال رنگ primary
|
||||
root.style.setProperty("--primary", oklchColor);
|
||||
|
||||
// محاسبه رنگ foreground متناسب
|
||||
const brightness = calculateBrightness(primaryColor);
|
||||
const foregroundOklch =
|
||||
brightness > 0.5 ? "oklch(0 0 0)" : "oklch(1 0 0)";
|
||||
root.style.setProperty("--primary-foreground", foregroundOklch);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error setting theme color:", error);
|
||||
}
|
||||
}, [primaryColor, enabled]);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { useState } from 'react'
|
||||
|
||||
const useToggle = (initial?: boolean) => {
|
||||
const [state, setState] = useState<boolean>(initial ?? false);
|
||||
|
||||
const toggle = (e?: React.MouseEvent | null) => {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
setState((prev) => !prev);
|
||||
}
|
||||
|
||||
const set = (value: boolean) => {
|
||||
setState(value);
|
||||
}
|
||||
|
||||
return { state, toggle, set }
|
||||
}
|
||||
|
||||
export default useToggle
|
||||
@@ -0,0 +1,51 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
export const useCountdown = (shouldStart: boolean, duration: number = 30, delay: number = 1000) => {
|
||||
const [timerRunning, setTimerRunning] = useState(false);
|
||||
const [secondsLeft, setSecondsLeft] = useState(duration);
|
||||
const intervalRef = useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (shouldStart) {
|
||||
setSecondsLeft(duration);
|
||||
setTimerRunning(true);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [shouldStart]);
|
||||
|
||||
const stop = () => {
|
||||
if (intervalRef.current) {
|
||||
clearInterval(intervalRef.current);
|
||||
intervalRef.current = null;
|
||||
}
|
||||
}
|
||||
|
||||
const restart = () => {
|
||||
stop();
|
||||
setSecondsLeft(duration);
|
||||
setTimerRunning(true);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (timerRunning && intervalRef.current === null) {
|
||||
intervalRef.current = setInterval(() => {
|
||||
setSecondsLeft((prev) => {
|
||||
if (prev <= 1) {
|
||||
setTimerRunning(false);
|
||||
clearInterval(intervalRef.current!);
|
||||
intervalRef.current = null;
|
||||
return 0;
|
||||
}
|
||||
return prev - 1;
|
||||
});
|
||||
}, delay);
|
||||
}
|
||||
|
||||
return () => {
|
||||
stop();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [timerRunning]);
|
||||
|
||||
return { timerRunning, secondsLeft, setTimerRunning, setSecondsLeft, stop, restart };
|
||||
};
|
||||
Reference in New Issue
Block a user