Convert useModified into a real hook.

This commit is contained in:
Mike Cao 2024-02-07 23:48:51 -08:00
parent a426c242cb
commit 91e3dff7f5
24 changed files with 63 additions and 48 deletions

View File

@ -1,6 +1,5 @@
import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics'; import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
import { useApi, useMessages } from 'components/hooks'; import { useApi, useMessages, useModified } from 'components/hooks';
import { touch } from 'store/modified';
import ConfirmationForm from 'components/common/ConfirmationForm'; import ConfirmationForm from 'components/common/ConfirmationForm';
export function ReportDeleteButton({ export function ReportDeleteButton({
@ -17,6 +16,7 @@ export function ReportDeleteButton({
const { mutate, isPending, error } = useMutation({ const { mutate, isPending, error } = useMutation({
mutationFn: reportId => del(`/reports/${reportId}`), mutationFn: reportId => del(`/reports/${reportId}`),
}); });
const { touch } = useModified();
const handleConfirm = (close: () => void) => { const handleConfirm = (close: () => void) => {
mutate(reportId as any, { mutate(reportId as any, {

View File

@ -8,14 +8,14 @@ import {
Button, Button,
SubmitButton, SubmitButton,
} from 'react-basics'; } from 'react-basics';
import { useApi, useMessages } from 'components/hooks'; import { useApi, useMessages, useModified } from 'components/hooks';
import { touch } from 'store/modified';
export function TeamJoinForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) { export function TeamJoinForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) {
const { formatMessage, labels, getMessage } = useMessages(); const { formatMessage, labels, getMessage } = useMessages();
const { post, useMutation } = useApi(); const { post, useMutation } = useApi();
const { mutate, error } = useMutation({ mutationFn: (data: any) => post('/teams/join', data) }); const { mutate, error } = useMutation({ mutationFn: (data: any) => post('/teams/join', data) });
const ref = useRef(null); const ref = useRef(null);
const { touch } = useModified();
const handleSubmit = async (data: any) => { const handleSubmit = async (data: any) => {
mutate(data, { mutate(data, {

View File

@ -1,7 +1,6 @@
import { useLocale, useLogin, useMessages } from 'components/hooks'; import { useLocale, useLogin, useMessages, useModified } from 'components/hooks';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics'; import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
import { touch } from 'store/modified';
import TeamDeleteForm from './TeamLeaveForm'; import TeamDeleteForm from './TeamLeaveForm';
export function TeamLeaveButton({ teamId, teamName }: { teamId: string; teamName: string }) { export function TeamLeaveButton({ teamId, teamName }: { teamId: string; teamName: string }) {
@ -9,6 +8,7 @@ export function TeamLeaveButton({ teamId, teamName }: { teamId: string; teamName
const router = useRouter(); const router = useRouter();
const { dir } = useLocale(); const { dir } = useLocale();
const { user } = useLogin(); const { user } = useLogin();
const { touch } = useModified();
const handleLeave = async () => { const handleLeave = async () => {
touch('teams'); touch('teams');

View File

@ -1,5 +1,4 @@
import { useApi, useMessages } from 'components/hooks'; import { useApi, useMessages, useModified } from 'components/hooks';
import { touch } from 'store/modified';
import ConfirmationForm from 'components/common/ConfirmationForm'; import ConfirmationForm from 'components/common/ConfirmationForm';
export function TeamLeaveForm({ export function TeamLeaveForm({
@ -20,6 +19,7 @@ export function TeamLeaveForm({
const { mutate, error, isPending } = useMutation({ const { mutate, error, isPending } = useMutation({
mutationFn: () => del(`/teams/${teamId}/users/${userId}`), mutationFn: () => del(`/teams/${teamId}/users/${userId}`),
}); });
const { touch } = useModified();
const handleConfirm = async () => { const handleConfirm = async () => {
mutate(null, { mutate(null, {

View File

@ -1,13 +1,13 @@
import { Button, Icon, Modal, ModalTrigger, Text, useToasts } from 'react-basics'; import { Button, Icon, Modal, ModalTrigger, Text, useToasts } from 'react-basics';
import Icons from 'components/icons'; import Icons from 'components/icons';
import { useMessages } from 'components/hooks'; import { useMessages, useModified } from 'components/hooks';
import TeamAddForm from './TeamAddForm'; import TeamAddForm from './TeamAddForm';
import { messages } from 'components/messages'; import { messages } from 'components/messages';
import { touch } from 'store/modified';
export function TeamsAddButton({ onSave }: { onSave?: () => void }) { export function TeamsAddButton({ onSave }: { onSave?: () => void }) {
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const { showToast } = useToasts(); const { showToast } = useToasts();
const { touch } = useModified();
const handleSave = async () => { const handleSave = async () => {
showToast({ message: formatMessage(messages.saved), variant: 'success' }); showToast({ message: formatMessage(messages.saved), variant: 'success' });

View File

@ -1,12 +1,12 @@
import { Button, Icon, Modal, ModalTrigger, Text, useToasts } from 'react-basics'; import { Button, Icon, Modal, ModalTrigger, Text, useToasts } from 'react-basics';
import Icons from 'components/icons'; import Icons from 'components/icons';
import { useMessages } from 'components/hooks'; import { useMessages, useModified } from 'components/hooks';
import TeamJoinForm from './TeamJoinForm'; import TeamJoinForm from './TeamJoinForm';
import { touch } from 'store/modified';
export function TeamsJoinButton() { export function TeamsJoinButton() {
const { formatMessage, labels, messages } = useMessages(); const { formatMessage, labels, messages } = useMessages();
const { showToast } = useToasts(); const { showToast } = useToasts();
const { touch } = useModified();
const handleJoin = () => { const handleJoin = () => {
showToast({ message: formatMessage(messages.saved), variant: 'success' }); showToast({ message: formatMessage(messages.saved), variant: 'success' });

View File

@ -1,6 +1,5 @@
import { useApi, useMessages } from 'components/hooks'; import { useApi, useMessages, useModified } from 'components/hooks';
import { Icon, Icons, LoadingButton, Text } from 'react-basics'; import { Icon, Icons, LoadingButton, Text } from 'react-basics';
import { touch } from 'store/modified';
export function TeamMemberRemoveButton({ export function TeamMemberRemoveButton({
teamId, teamId,
@ -18,6 +17,7 @@ export function TeamMemberRemoveButton({
const { mutate, isPending } = useMutation({ const { mutate, isPending } = useMutation({
mutationFn: () => del(`/teams/${teamId}/users/${userId}`), mutationFn: () => del(`/teams/${teamId}/users/${userId}`),
}); });
const { touch } = useModified();
const handleRemoveTeamMember = () => { const handleRemoveTeamMember = () => {
mutate(null, { mutate(null, {

View File

@ -1,12 +1,12 @@
import { useMessages } from 'components/hooks'; import { useMessages, useModified } from 'components/hooks';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { ActionForm, Button, Modal, ModalTrigger } from 'react-basics'; import { ActionForm, Button, Modal, ModalTrigger } from 'react-basics';
import TeamDeleteForm from './TeamDeleteForm'; import TeamDeleteForm from './TeamDeleteForm';
import { touch } from 'store/modified';
export function TeamAdmin({ teamId }: { teamId: string }) { export function TeamAdmin({ teamId }: { teamId: string }) {
const { formatMessage, labels, messages } = useMessages(); const { formatMessage, labels, messages } = useMessages();
const router = useRouter(); const router = useRouter();
const { touch } = useModified();
const handleLeave = async () => { const handleLeave = async () => {
touch('teams'); touch('teams');

View File

@ -1,11 +1,11 @@
import { Button, Icon, Text, Modal, Icons, ModalTrigger, useToasts } from 'react-basics'; import { Button, Icon, Text, Modal, Icons, ModalTrigger, useToasts } from 'react-basics';
import UserAddForm from './UserAddForm'; import UserAddForm from './UserAddForm';
import { useMessages } from 'components/hooks'; import { useMessages, useModified } from 'components/hooks';
import { touch } from 'store/modified';
export function UserAddButton({ onSave }: { onSave?: () => void }) { export function UserAddButton({ onSave }: { onSave?: () => void }) {
const { formatMessage, labels, messages } = useMessages(); const { formatMessage, labels, messages } = useMessages();
const { showToast } = useToasts(); const { showToast } = useToasts();
const { touch } = useModified();
const handleSave = () => { const handleSave = () => {
showToast({ message: formatMessage(messages.saved), variant: 'success' }); showToast({ message: formatMessage(messages.saved), variant: 'success' });

View File

@ -1,11 +1,11 @@
import { useApi, useMessages } from 'components/hooks'; import { useApi, useMessages, useModified } from 'components/hooks';
import ConfirmationForm from 'components/common/ConfirmationForm'; import ConfirmationForm from 'components/common/ConfirmationForm';
import { touch } from 'store/modified';
export function UserDeleteForm({ userId, username, onSave, onClose }) { export function UserDeleteForm({ userId, username, onSave, onClose }) {
const { FormattedMessage, messages, labels, formatMessage } = useMessages(); const { FormattedMessage, messages, labels, formatMessage } = useMessages();
const { del, useMutation } = useApi(); const { del, useMutation } = useApi();
const { mutate, error, isPending } = useMutation({ mutationFn: () => del(`/users/${userId}`) }); const { mutate, error, isPending } = useMutation({ mutationFn: () => del(`/users/${userId}`) });
const { touch } = useModified();
const handleConfirm = async () => { const handleConfirm = async () => {
mutate(null, { mutate(null, {

View File

@ -1,11 +1,11 @@
import { useMessages } from 'components/hooks'; import { useMessages, useModified } from 'components/hooks';
import { Button, Icon, Icons, Modal, ModalTrigger, Text, useToasts } from 'react-basics'; import { Button, Icon, Icons, Modal, ModalTrigger, Text, useToasts } from 'react-basics';
import { touch } from 'store/modified';
import WebsiteAddForm from './WebsiteAddForm'; import WebsiteAddForm from './WebsiteAddForm';
export function WebsiteAddButton({ teamId, onSave }: { teamId: string; onSave?: () => void }) { export function WebsiteAddButton({ teamId, onSave }: { teamId: string; onSave?: () => void }) {
const { formatMessage, labels, messages } = useMessages(); const { formatMessage, labels, messages } = useMessages();
const { showToast } = useToasts(); const { showToast } = useToasts();
const { touch } = useModified();
const handleSave = async () => { const handleSave = async () => {
showToast({ message: formatMessage(messages.saved), variant: 'success' }); showToast({ message: formatMessage(messages.saved), variant: 'success' });

View File

@ -11,9 +11,8 @@ import {
} from 'react-basics'; } from 'react-basics';
import { useContext, useState } from 'react'; import { useContext, useState } from 'react';
import { getRandomChars } from 'next-basics'; import { getRandomChars } from 'next-basics';
import { useApi, useMessages } from 'components/hooks'; import { useApi, useMessages, useModified } from 'components/hooks';
import { WebsiteContext } from 'app/(main)/websites/[websiteId]/WebsiteProvider'; import { WebsiteContext } from 'app/(main)/websites/[websiteId]/WebsiteProvider';
import { touch } from 'store/modified';
const generateId = () => getRandomChars(16); const generateId = () => getRandomChars(16);
@ -33,6 +32,7 @@ export function ShareUrl({
const { mutate, error, isPending } = useMutation({ const { mutate, error, isPending } = useMutation({
mutationFn: (data: any) => post(`/websites/${website.id}`, data), mutationFn: (data: any) => post(`/websites/${website.id}`, data),
}); });
const { touch } = useModified();
const url = `${hostUrl || process.env.hostUrl || window?.location.origin}${ const url = `${hostUrl || process.env.hostUrl || window?.location.origin}${
process.env.basePath process.env.basePath

View File

@ -1,14 +1,14 @@
import { Button, Modal, ModalTrigger, ActionForm, useToasts } from 'react-basics'; import { Button, Modal, ModalTrigger, ActionForm, useToasts } from 'react-basics';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useMessages } from 'components/hooks'; import { useMessages, useModified } from 'components/hooks';
import WebsiteDeleteForm from './WebsiteDeleteForm'; import WebsiteDeleteForm from './WebsiteDeleteForm';
import WebsiteResetForm from './WebsiteResetForm'; import WebsiteResetForm from './WebsiteResetForm';
import { touch } from 'store/modified';
export function WebsiteData({ websiteId, onSave }: { websiteId: string; onSave?: () => void }) { export function WebsiteData({ websiteId, onSave }: { websiteId: string; onSave?: () => void }) {
const { formatMessage, labels, messages } = useMessages(); const { formatMessage, labels, messages } = useMessages();
const router = useRouter(); const router = useRouter();
const { showToast } = useToasts(); const { showToast } = useToasts();
const { touch } = useModified();
const handleReset = async () => { const handleReset = async () => {
showToast({ message: formatMessage(messages.saved), variant: 'success' }); showToast({ message: formatMessage(messages.saved), variant: 'success' });

View File

@ -8,9 +8,8 @@ import {
TextField, TextField,
useToasts, useToasts,
} from 'react-basics'; } from 'react-basics';
import { useApi, useMessages } from 'components/hooks'; import { useApi, useMessages, useModified } from 'components/hooks';
import { DOMAIN_REGEX } from 'lib/constants'; import { DOMAIN_REGEX } from 'lib/constants';
import { touch } from 'store/modified';
import { WebsiteContext } from 'app/(main)/websites/[websiteId]/WebsiteProvider'; import { WebsiteContext } from 'app/(main)/websites/[websiteId]/WebsiteProvider';
export function WebsiteEditForm({ websiteId }: { websiteId: string }) { export function WebsiteEditForm({ websiteId }: { websiteId: string }) {
@ -22,6 +21,7 @@ export function WebsiteEditForm({ websiteId }: { websiteId: string }) {
}); });
const ref = useRef(null); const ref = useRef(null);
const { showToast } = useToasts(); const { showToast } = useToasts();
const { touch } = useModified();
const handleSubmit = async (data: any) => { const handleSubmit = async (data: any) => {
mutate(data, { mutate(data, {

View File

@ -1,13 +1,12 @@
'use client'; 'use client';
import { createContext, ReactNode, useEffect } from 'react'; import { createContext, ReactNode, useEffect } from 'react';
import { useTeam } from 'components/hooks'; import { useTeam, useModified } from 'components/hooks';
import { Loading } from 'react-basics'; import { Loading } from 'react-basics';
import useModified from 'store/modified';
export const TeamContext = createContext(null); export const TeamContext = createContext(null);
export function TeamProvider({ teamId, children }: { teamId?: string; children: ReactNode }) { export function TeamProvider({ teamId, children }: { teamId?: string; children: ReactNode }) {
const modified = useModified(state => state?.[`team:${teamId}`]); const { modified } = useModified(`teams`);
const { data: team, isLoading, isFetching, refetch } = useTeam(teamId); const { data: team, isLoading, isFetching, refetch } = useTeam(teamId);
useEffect(() => { useEffect(() => {

View File

@ -1,7 +1,6 @@
import { createContext, ReactNode, useEffect } from 'react'; import { createContext, ReactNode, useEffect } from 'react';
import { useWebsite } from 'components/hooks'; import { useModified, useWebsite } from 'components/hooks';
import { Loading } from 'react-basics'; import { Loading } from 'react-basics';
import useModified from 'store/modified';
export const WebsiteContext = createContext(null); export const WebsiteContext = createContext(null);
@ -12,7 +11,7 @@ export function WebsiteProvider({
websiteId: string; websiteId: string;
children: ReactNode; children: ReactNode;
}) { }) {
const modified = useModified(state => state?.[`website:${websiteId}`]); const { modified } = useModified(`website:${websiteId}`);
const { data: website, isFetching, isLoading, refetch } = useWebsite(websiteId); const { data: website, isFetching, isLoading, refetch } = useWebsite(websiteId);
useEffect(() => { useEffect(() => {

View File

@ -25,6 +25,7 @@ export * from './useFormat';
export * from './useLanguageNames'; export * from './useLanguageNames';
export * from './useLocale'; export * from './useLocale';
export * from './useMessages'; export * from './useMessages';
export * from './useModified';
export * from './useNavigation'; export * from './useNavigation';
export * from './useSticky'; export * from './useSticky';
export * from './useTeamUrl'; export * from './useTeamUrl';

View File

@ -1,9 +1,9 @@
import useApi from './useApi'; import useApi from './useApi';
import useFilterQuery from './useFilterQuery'; import useFilterQuery from './useFilterQuery';
import useModified from 'store/modified'; import useModified from '../useModified';
export function useReports({ websiteId, teamId }: { websiteId?: string; teamId?: string }) { export function useReports({ websiteId, teamId }: { websiteId?: string; teamId?: string }) {
const modified = useModified((state: any) => state?.reports); const { modified } = useModified(`reports`);
const { get, del, useMutation } = useApi(); const { get, del, useMutation } = useApi();
const queryResult = useFilterQuery({ const queryResult = useFilterQuery({
queryKey: ['reports', { websiteId, teamId, modified }], queryKey: ['reports', { websiteId, teamId, modified }],

View File

@ -1,10 +1,10 @@
import useApi from './useApi'; import useApi from './useApi';
import useFilterQuery from './useFilterQuery'; import useFilterQuery from './useFilterQuery';
import useModified from 'store/modified'; import useModified from '../useModified';
export function useTeamMembers(teamId: string) { export function useTeamMembers(teamId: string) {
const { get } = useApi(); const { get } = useApi();
const modified = useModified((state: any) => state?.['teams:members']); const { modified } = useModified(`teams:members`);
return useFilterQuery({ return useFilterQuery({
queryKey: ['teams:members', { teamId, modified }], queryKey: ['teams:members', { teamId, modified }],

View File

@ -1,10 +1,10 @@
import useApi from './useApi'; import useApi from './useApi';
import useFilterQuery from './useFilterQuery'; import useFilterQuery from './useFilterQuery';
import useModified from 'store/modified'; import useModified from '../useModified';
export function useTeamWebsites(teamId: string) { export function useTeamWebsites(teamId: string) {
const { get } = useApi(); const { get } = useApi();
const modified = useModified((state: any) => state?.['teams:websites']); const { modified } = useModified(`teams:websites`);
return useFilterQuery({ return useFilterQuery({
queryKey: ['teams:websites', { teamId, modified }], queryKey: ['teams:websites', { teamId, modified }],

View File

@ -1,15 +1,16 @@
import useApi from './useApi'; import useApi from './useApi';
import useFilterQuery from './useFilterQuery'; import useFilterQuery from './useFilterQuery';
import { useLogin } from 'components/hooks'; import useLogin from './useLogin';
import useModified from 'store/modified'; import useModified from '../useModified';
export function useTeams(userId?: string) { export function useTeams(userId?: string) {
const { get } = useApi(); const { get } = useApi();
const { user } = useLogin(); const { user } = useLogin();
const modified = useModified((state: any) => state?.teams); const id = userId || user?.id;
const { modified } = useModified(`teams`);
return useFilterQuery({ return useFilterQuery({
queryKey: ['teams', { userId: userId || user?.id, modified }], queryKey: ['teams', { userId: id, modified }],
queryFn: (params: any) => { queryFn: (params: any) => {
return get(`/teams`, params); return get(`/teams`, params);
}, },

View File

@ -1,10 +1,10 @@
import useApi from './useApi'; import useApi from './useApi';
import useFilterQuery from './useFilterQuery'; import useFilterQuery from './useFilterQuery';
import useModified from 'store/modified'; import useModified from '../useModified';
export function useUsers() { export function useUsers() {
const { get } = useApi(); const { get } = useApi();
const modified = useModified((state: any) => state?.users); const { modified } = useModified(`users`);
return useFilterQuery({ return useFilterQuery({
queryKey: ['users', { modified }], queryKey: ['users', { modified }],

View File

@ -1,7 +1,7 @@
import { useApi } from './useApi'; import { useApi } from './useApi';
import { useFilterQuery } from './useFilterQuery'; import { useFilterQuery } from './useFilterQuery';
import { useLogin } from './useLogin'; import { useLogin } from './useLogin';
import useModified from 'store/modified'; import useModified from '../useModified';
export function useWebsites( export function useWebsites(
{ userId, teamId }: { userId?: string; teamId?: string }, { userId, teamId }: { userId?: string; teamId?: string },
@ -9,7 +9,7 @@ export function useWebsites(
) { ) {
const { get } = useApi(); const { get } = useApi();
const { user } = useLogin(); const { user } = useLogin();
const modified = useModified((state: any) => state?.websites); const { modified } = useModified(`websites`);
return useFilterQuery({ return useFilterQuery({
queryKey: ['websites', { userId, teamId, modified, ...params }], queryKey: ['websites', { userId, teamId, modified, ...params }],

View File

@ -0,0 +1,15 @@
import useStore from 'store/modified';
export function useModified(key?: string) {
const modified = useStore(state => state?.[key]);
const touch = (id?: string) => {
if (id || key) {
useStore.setState({ [id || key]: Date.now() });
}
};
return { modified, touch };
}
export default useModified;