diff --git a/src/app/(main)/reports/ReportDeleteButton.tsx b/src/app/(main)/reports/ReportDeleteButton.tsx index affd81fd..7ad9c465 100644 --- a/src/app/(main)/reports/ReportDeleteButton.tsx +++ b/src/app/(main)/reports/ReportDeleteButton.tsx @@ -1,6 +1,5 @@ import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics'; -import { useApi, useMessages } from 'components/hooks'; -import { touch } from 'store/modified'; +import { useApi, useMessages, useModified } from 'components/hooks'; import ConfirmationForm from 'components/common/ConfirmationForm'; export function ReportDeleteButton({ @@ -17,6 +16,7 @@ export function ReportDeleteButton({ const { mutate, isPending, error } = useMutation({ mutationFn: reportId => del(`/reports/${reportId}`), }); + const { touch } = useModified(); const handleConfirm = (close: () => void) => { mutate(reportId as any, { diff --git a/src/app/(main)/settings/teams/TeamJoinForm.tsx b/src/app/(main)/settings/teams/TeamJoinForm.tsx index 385ff1df..939b5d4b 100644 --- a/src/app/(main)/settings/teams/TeamJoinForm.tsx +++ b/src/app/(main)/settings/teams/TeamJoinForm.tsx @@ -8,14 +8,14 @@ import { Button, SubmitButton, } from 'react-basics'; -import { useApi, useMessages } from 'components/hooks'; -import { touch } from 'store/modified'; +import { useApi, useMessages, useModified } from 'components/hooks'; export function TeamJoinForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) { const { formatMessage, labels, getMessage } = useMessages(); const { post, useMutation } = useApi(); const { mutate, error } = useMutation({ mutationFn: (data: any) => post('/teams/join', data) }); const ref = useRef(null); + const { touch } = useModified(); const handleSubmit = async (data: any) => { mutate(data, { diff --git a/src/app/(main)/settings/teams/TeamLeaveButton.tsx b/src/app/(main)/settings/teams/TeamLeaveButton.tsx index 308f8fb9..b8a24c7e 100644 --- a/src/app/(main)/settings/teams/TeamLeaveButton.tsx +++ b/src/app/(main)/settings/teams/TeamLeaveButton.tsx @@ -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 { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics'; -import { touch } from 'store/modified'; import TeamDeleteForm from './TeamLeaveForm'; 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 { dir } = useLocale(); const { user } = useLogin(); + const { touch } = useModified(); const handleLeave = async () => { touch('teams'); diff --git a/src/app/(main)/settings/teams/TeamLeaveForm.tsx b/src/app/(main)/settings/teams/TeamLeaveForm.tsx index 980a8cb7..8c9726be 100644 --- a/src/app/(main)/settings/teams/TeamLeaveForm.tsx +++ b/src/app/(main)/settings/teams/TeamLeaveForm.tsx @@ -1,5 +1,4 @@ -import { useApi, useMessages } from 'components/hooks'; -import { touch } from 'store/modified'; +import { useApi, useMessages, useModified } from 'components/hooks'; import ConfirmationForm from 'components/common/ConfirmationForm'; export function TeamLeaveForm({ @@ -20,6 +19,7 @@ export function TeamLeaveForm({ const { mutate, error, isPending } = useMutation({ mutationFn: () => del(`/teams/${teamId}/users/${userId}`), }); + const { touch } = useModified(); const handleConfirm = async () => { mutate(null, { diff --git a/src/app/(main)/settings/teams/TeamsAddButton.tsx b/src/app/(main)/settings/teams/TeamsAddButton.tsx index 15f541ea..6ec4cf39 100644 --- a/src/app/(main)/settings/teams/TeamsAddButton.tsx +++ b/src/app/(main)/settings/teams/TeamsAddButton.tsx @@ -1,13 +1,13 @@ import { Button, Icon, Modal, ModalTrigger, Text, useToasts } from 'react-basics'; import Icons from 'components/icons'; -import { useMessages } from 'components/hooks'; +import { useMessages, useModified } from 'components/hooks'; import TeamAddForm from './TeamAddForm'; import { messages } from 'components/messages'; -import { touch } from 'store/modified'; export function TeamsAddButton({ onSave }: { onSave?: () => void }) { const { formatMessage, labels } = useMessages(); const { showToast } = useToasts(); + const { touch } = useModified(); const handleSave = async () => { showToast({ message: formatMessage(messages.saved), variant: 'success' }); diff --git a/src/app/(main)/settings/teams/TeamsJoinButton.tsx b/src/app/(main)/settings/teams/TeamsJoinButton.tsx index 21f821c9..24925bb6 100644 --- a/src/app/(main)/settings/teams/TeamsJoinButton.tsx +++ b/src/app/(main)/settings/teams/TeamsJoinButton.tsx @@ -1,12 +1,12 @@ import { Button, Icon, Modal, ModalTrigger, Text, useToasts } from 'react-basics'; import Icons from 'components/icons'; -import { useMessages } from 'components/hooks'; +import { useMessages, useModified } from 'components/hooks'; import TeamJoinForm from './TeamJoinForm'; -import { touch } from 'store/modified'; export function TeamsJoinButton() { const { formatMessage, labels, messages } = useMessages(); const { showToast } = useToasts(); + const { touch } = useModified(); const handleJoin = () => { showToast({ message: formatMessage(messages.saved), variant: 'success' }); diff --git a/src/app/(main)/settings/teams/[teamId]/members/TeamMemberRemoveButton.tsx b/src/app/(main)/settings/teams/[teamId]/members/TeamMemberRemoveButton.tsx index fc51a818..bb944061 100644 --- a/src/app/(main)/settings/teams/[teamId]/members/TeamMemberRemoveButton.tsx +++ b/src/app/(main)/settings/teams/[teamId]/members/TeamMemberRemoveButton.tsx @@ -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 { touch } from 'store/modified'; export function TeamMemberRemoveButton({ teamId, @@ -18,6 +17,7 @@ export function TeamMemberRemoveButton({ const { mutate, isPending } = useMutation({ mutationFn: () => del(`/teams/${teamId}/users/${userId}`), }); + const { touch } = useModified(); const handleRemoveTeamMember = () => { mutate(null, { diff --git a/src/app/(main)/settings/teams/[teamId]/team/TeamAdmin.tsx b/src/app/(main)/settings/teams/[teamId]/team/TeamAdmin.tsx index b52b661e..2c0a20d2 100644 --- a/src/app/(main)/settings/teams/[teamId]/team/TeamAdmin.tsx +++ b/src/app/(main)/settings/teams/[teamId]/team/TeamAdmin.tsx @@ -1,12 +1,12 @@ -import { useMessages } from 'components/hooks'; +import { useMessages, useModified } from 'components/hooks'; import { useRouter } from 'next/navigation'; import { ActionForm, Button, Modal, ModalTrigger } from 'react-basics'; import TeamDeleteForm from './TeamDeleteForm'; -import { touch } from 'store/modified'; export function TeamAdmin({ teamId }: { teamId: string }) { const { formatMessage, labels, messages } = useMessages(); const router = useRouter(); + const { touch } = useModified(); const handleLeave = async () => { touch('teams'); diff --git a/src/app/(main)/settings/users/UserAddButton.tsx b/src/app/(main)/settings/users/UserAddButton.tsx index 5746ff2a..832cf75b 100644 --- a/src/app/(main)/settings/users/UserAddButton.tsx +++ b/src/app/(main)/settings/users/UserAddButton.tsx @@ -1,11 +1,11 @@ import { Button, Icon, Text, Modal, Icons, ModalTrigger, useToasts } from 'react-basics'; import UserAddForm from './UserAddForm'; -import { useMessages } from 'components/hooks'; -import { touch } from 'store/modified'; +import { useMessages, useModified } from 'components/hooks'; export function UserAddButton({ onSave }: { onSave?: () => void }) { const { formatMessage, labels, messages } = useMessages(); const { showToast } = useToasts(); + const { touch } = useModified(); const handleSave = () => { showToast({ message: formatMessage(messages.saved), variant: 'success' }); diff --git a/src/app/(main)/settings/users/UserDeleteForm.tsx b/src/app/(main)/settings/users/UserDeleteForm.tsx index 97caf644..9b49647f 100644 --- a/src/app/(main)/settings/users/UserDeleteForm.tsx +++ b/src/app/(main)/settings/users/UserDeleteForm.tsx @@ -1,11 +1,11 @@ -import { useApi, useMessages } from 'components/hooks'; +import { useApi, useMessages, useModified } from 'components/hooks'; import ConfirmationForm from 'components/common/ConfirmationForm'; -import { touch } from 'store/modified'; export function UserDeleteForm({ userId, username, onSave, onClose }) { const { FormattedMessage, messages, labels, formatMessage } = useMessages(); const { del, useMutation } = useApi(); const { mutate, error, isPending } = useMutation({ mutationFn: () => del(`/users/${userId}`) }); + const { touch } = useModified(); const handleConfirm = async () => { mutate(null, { diff --git a/src/app/(main)/settings/websites/WebsiteAddButton.tsx b/src/app/(main)/settings/websites/WebsiteAddButton.tsx index 58b3001c..8f0b2091 100644 --- a/src/app/(main)/settings/websites/WebsiteAddButton.tsx +++ b/src/app/(main)/settings/websites/WebsiteAddButton.tsx @@ -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 { touch } from 'store/modified'; import WebsiteAddForm from './WebsiteAddForm'; export function WebsiteAddButton({ teamId, onSave }: { teamId: string; onSave?: () => void }) { const { formatMessage, labels, messages } = useMessages(); const { showToast } = useToasts(); + const { touch } = useModified(); const handleSave = async () => { showToast({ message: formatMessage(messages.saved), variant: 'success' }); diff --git a/src/app/(main)/settings/websites/[websiteId]/ShareUrl.tsx b/src/app/(main)/settings/websites/[websiteId]/ShareUrl.tsx index 6fb543d0..e06657d4 100644 --- a/src/app/(main)/settings/websites/[websiteId]/ShareUrl.tsx +++ b/src/app/(main)/settings/websites/[websiteId]/ShareUrl.tsx @@ -11,9 +11,8 @@ import { } from 'react-basics'; import { useContext, useState } from 'react'; 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 { touch } from 'store/modified'; const generateId = () => getRandomChars(16); @@ -33,6 +32,7 @@ export function ShareUrl({ const { mutate, error, isPending } = useMutation({ mutationFn: (data: any) => post(`/websites/${website.id}`, data), }); + const { touch } = useModified(); const url = `${hostUrl || process.env.hostUrl || window?.location.origin}${ process.env.basePath diff --git a/src/app/(main)/settings/websites/[websiteId]/WebsiteData.tsx b/src/app/(main)/settings/websites/[websiteId]/WebsiteData.tsx index 4dd5fde4..c75ef74b 100644 --- a/src/app/(main)/settings/websites/[websiteId]/WebsiteData.tsx +++ b/src/app/(main)/settings/websites/[websiteId]/WebsiteData.tsx @@ -1,14 +1,14 @@ import { Button, Modal, ModalTrigger, ActionForm, useToasts } from 'react-basics'; import { useRouter } from 'next/navigation'; -import { useMessages } from 'components/hooks'; +import { useMessages, useModified } from 'components/hooks'; import WebsiteDeleteForm from './WebsiteDeleteForm'; import WebsiteResetForm from './WebsiteResetForm'; -import { touch } from 'store/modified'; export function WebsiteData({ websiteId, onSave }: { websiteId: string; onSave?: () => void }) { const { formatMessage, labels, messages } = useMessages(); const router = useRouter(); const { showToast } = useToasts(); + const { touch } = useModified(); const handleReset = async () => { showToast({ message: formatMessage(messages.saved), variant: 'success' }); diff --git a/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx b/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx index 543261dd..d7d9cef4 100644 --- a/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx +++ b/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx @@ -8,9 +8,8 @@ import { TextField, useToasts, } from 'react-basics'; -import { useApi, useMessages } from 'components/hooks'; +import { useApi, useMessages, useModified } from 'components/hooks'; import { DOMAIN_REGEX } from 'lib/constants'; -import { touch } from 'store/modified'; import { WebsiteContext } from 'app/(main)/websites/[websiteId]/WebsiteProvider'; export function WebsiteEditForm({ websiteId }: { websiteId: string }) { @@ -22,6 +21,7 @@ export function WebsiteEditForm({ websiteId }: { websiteId: string }) { }); const ref = useRef(null); const { showToast } = useToasts(); + const { touch } = useModified(); const handleSubmit = async (data: any) => { mutate(data, { diff --git a/src/app/(main)/teams/[teamId]/TeamProvider.tsx b/src/app/(main)/teams/[teamId]/TeamProvider.tsx index 02a7e1b8..a9c57cec 100644 --- a/src/app/(main)/teams/[teamId]/TeamProvider.tsx +++ b/src/app/(main)/teams/[teamId]/TeamProvider.tsx @@ -1,13 +1,12 @@ 'use client'; import { createContext, ReactNode, useEffect } from 'react'; -import { useTeam } from 'components/hooks'; +import { useTeam, useModified } from 'components/hooks'; import { Loading } from 'react-basics'; -import useModified from 'store/modified'; export const TeamContext = createContext(null); 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); useEffect(() => { diff --git a/src/app/(main)/websites/[websiteId]/WebsiteProvider.tsx b/src/app/(main)/websites/[websiteId]/WebsiteProvider.tsx index e1d3da26..76d40b70 100644 --- a/src/app/(main)/websites/[websiteId]/WebsiteProvider.tsx +++ b/src/app/(main)/websites/[websiteId]/WebsiteProvider.tsx @@ -1,7 +1,6 @@ import { createContext, ReactNode, useEffect } from 'react'; -import { useWebsite } from 'components/hooks'; +import { useModified, useWebsite } from 'components/hooks'; import { Loading } from 'react-basics'; -import useModified from 'store/modified'; export const WebsiteContext = createContext(null); @@ -12,7 +11,7 @@ export function WebsiteProvider({ websiteId: string; children: ReactNode; }) { - const modified = useModified(state => state?.[`website:${websiteId}`]); + const { modified } = useModified(`website:${websiteId}`); const { data: website, isFetching, isLoading, refetch } = useWebsite(websiteId); useEffect(() => { diff --git a/src/components/hooks/index.ts b/src/components/hooks/index.ts index 79cefcfd..560d48a0 100644 --- a/src/components/hooks/index.ts +++ b/src/components/hooks/index.ts @@ -25,6 +25,7 @@ export * from './useFormat'; export * from './useLanguageNames'; export * from './useLocale'; export * from './useMessages'; +export * from './useModified'; export * from './useNavigation'; export * from './useSticky'; export * from './useTeamUrl'; diff --git a/src/components/hooks/queries/useReports.ts b/src/components/hooks/queries/useReports.ts index 0e0f260b..314880f8 100644 --- a/src/components/hooks/queries/useReports.ts +++ b/src/components/hooks/queries/useReports.ts @@ -1,9 +1,9 @@ import useApi from './useApi'; import useFilterQuery from './useFilterQuery'; -import useModified from 'store/modified'; +import useModified from '../useModified'; 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 queryResult = useFilterQuery({ queryKey: ['reports', { websiteId, teamId, modified }], diff --git a/src/components/hooks/queries/useTeamMembers.ts b/src/components/hooks/queries/useTeamMembers.ts index 866e28e7..85860870 100644 --- a/src/components/hooks/queries/useTeamMembers.ts +++ b/src/components/hooks/queries/useTeamMembers.ts @@ -1,10 +1,10 @@ import useApi from './useApi'; import useFilterQuery from './useFilterQuery'; -import useModified from 'store/modified'; +import useModified from '../useModified'; export function useTeamMembers(teamId: string) { const { get } = useApi(); - const modified = useModified((state: any) => state?.['teams:members']); + const { modified } = useModified(`teams:members`); return useFilterQuery({ queryKey: ['teams:members', { teamId, modified }], diff --git a/src/components/hooks/queries/useTeamWebsites.ts b/src/components/hooks/queries/useTeamWebsites.ts index 5259f9d3..06e12a82 100644 --- a/src/components/hooks/queries/useTeamWebsites.ts +++ b/src/components/hooks/queries/useTeamWebsites.ts @@ -1,10 +1,10 @@ import useApi from './useApi'; import useFilterQuery from './useFilterQuery'; -import useModified from 'store/modified'; +import useModified from '../useModified'; export function useTeamWebsites(teamId: string) { const { get } = useApi(); - const modified = useModified((state: any) => state?.['teams:websites']); + const { modified } = useModified(`teams:websites`); return useFilterQuery({ queryKey: ['teams:websites', { teamId, modified }], diff --git a/src/components/hooks/queries/useTeams.ts b/src/components/hooks/queries/useTeams.ts index 3360a6c4..f8084025 100644 --- a/src/components/hooks/queries/useTeams.ts +++ b/src/components/hooks/queries/useTeams.ts @@ -1,15 +1,16 @@ import useApi from './useApi'; import useFilterQuery from './useFilterQuery'; -import { useLogin } from 'components/hooks'; -import useModified from 'store/modified'; +import useLogin from './useLogin'; +import useModified from '../useModified'; export function useTeams(userId?: string) { const { get } = useApi(); const { user } = useLogin(); - const modified = useModified((state: any) => state?.teams); + const id = userId || user?.id; + const { modified } = useModified(`teams`); return useFilterQuery({ - queryKey: ['teams', { userId: userId || user?.id, modified }], + queryKey: ['teams', { userId: id, modified }], queryFn: (params: any) => { return get(`/teams`, params); }, diff --git a/src/components/hooks/queries/useUsers.ts b/src/components/hooks/queries/useUsers.ts index ab897c17..169cf424 100644 --- a/src/components/hooks/queries/useUsers.ts +++ b/src/components/hooks/queries/useUsers.ts @@ -1,10 +1,10 @@ import useApi from './useApi'; import useFilterQuery from './useFilterQuery'; -import useModified from 'store/modified'; +import useModified from '../useModified'; export function useUsers() { const { get } = useApi(); - const modified = useModified((state: any) => state?.users); + const { modified } = useModified(`users`); return useFilterQuery({ queryKey: ['users', { modified }], diff --git a/src/components/hooks/queries/useWebsites.ts b/src/components/hooks/queries/useWebsites.ts index 4f16e4d8..94198975 100644 --- a/src/components/hooks/queries/useWebsites.ts +++ b/src/components/hooks/queries/useWebsites.ts @@ -1,7 +1,7 @@ import { useApi } from './useApi'; import { useFilterQuery } from './useFilterQuery'; import { useLogin } from './useLogin'; -import useModified from 'store/modified'; +import useModified from '../useModified'; export function useWebsites( { userId, teamId }: { userId?: string; teamId?: string }, @@ -9,7 +9,7 @@ export function useWebsites( ) { const { get } = useApi(); const { user } = useLogin(); - const modified = useModified((state: any) => state?.websites); + const { modified } = useModified(`websites`); return useFilterQuery({ queryKey: ['websites', { userId, teamId, modified, ...params }], diff --git a/src/components/hooks/useModified.ts b/src/components/hooks/useModified.ts new file mode 100644 index 00000000..858be87e --- /dev/null +++ b/src/components/hooks/useModified.ts @@ -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;