Files
mtdb_movie/common/resources/client/utils/hooks/use-cookie.ts
maher 703f50a09d
Some checks failed
Build / run (push) Has been cancelled
first commit
2025-10-29 11:42:25 +01:00

105 lines
2.3 KiB
TypeScript
Executable File

import {useCallback, useEffect, useState} from 'react';
import {isSsr} from '@common/utils/dom/is-ssr';
interface Options {
days?: number;
path?: string;
domain?: string;
SameSite?: 'None' | 'Lax' | 'Strict';
Secure?: boolean;
HttpOnly?: boolean;
}
// used to notify different instances of useCookie hook about cookie changes
const listeners = new Set<{name: string; callback: any}>();
const listenForCookieChange = (
name: string,
callback: (value: string) => void,
) => {
if (isSsr()) return () => {};
const listener = {name, callback};
listeners.add(listener);
return () => {
listeners.delete(listener);
};
};
export function stringifyOptions(options: Options) {
return Object.keys(options).reduce((acc, _key) => {
const key = _key as keyof Options;
if (key === 'days') {
return acc;
} else {
if (options[key] === false) {
return acc;
} else if (options[key] === true) {
return `${acc}; ${key}`;
} else {
return `${acc}; ${key}=${options[key]}`;
}
}
}, '');
}
export const setCookie = (name: string, value: string, options?: Options) => {
if (isSsr()) return;
const optionsWithDefaults = {
days: 7,
path: '/',
...options,
};
const expires = new Date(
Date.now() + optionsWithDefaults.days * 864e5,
).toUTCString();
document.cookie =
name +
'=' +
encodeURIComponent(value) +
'; expires=' +
expires +
stringifyOptions(optionsWithDefaults);
listeners.forEach(listener => {
if (listener.name === name) {
listener.callback(value);
}
});
};
export function getCookie(name: string, initialValue = '') {
return (
(!isSsr() &&
document.cookie &&
document.cookie.split('; ').reduce((r, v) => {
const parts = v.split('=');
return parts[0] === name ? decodeURIComponent(parts[1]) : r;
}, '')) ||
initialValue
);
}
export function useCookie(key: string, initialValue?: string) {
const [item, setItem] = useState(() => {
return getCookie(key, initialValue);
});
useEffect(() => {
return listenForCookieChange(key, value => {
setItem(value);
});
}, [key]);
const updateItem = useCallback(
(value: string, options?: Options) => {
setItem(value);
setCookie(key, value, options);
},
[key],
);
return [item, updateItem] as const;
}