diff --git a/src/components/appointment/AppointmentCard.tsx b/src/components/appointment/AppointmentCard.tsx index 04a9a22da..48166754f 100644 --- a/src/components/appointment/AppointmentCard.tsx +++ b/src/components/appointment/AppointmentCard.tsx @@ -14,8 +14,10 @@ import React, { useState } from 'react' import { useIntl } from 'react-intl' import styled from 'styled-components' import hasura from '../../hasura' -import { dateRangeFormatter } from '../../helpers' +import { dateRangeFormatter, handleError } from '../../helpers' import { useAppointmentPlan, useCancelAppointment, useUpdateAppointmentIssue } from '../../hooks/appointment' +import { GetMeetByTargetAndPeriod } from '../../hooks/meet' +import { useService } from '../../hooks/service' import DefaultAvatar from '../../images/avatar.svg' import { ReactComponent as CalendarOIcon } from '../../images/calendar-alt-o.svg' import { ReactComponent as UserOIcon } from '../../images/user-o.svg' @@ -128,16 +130,11 @@ type AppointmentCardProps = FormComponentProps & { } type AppointmentCardCreatorBlockProps = { - creator: { - avatarUrl: string | null - name: string | null - } - appointmentPlan: AppointmentPlan | null + appointmentPlan: (AppointmentPlan & { creator: { id: string; name: string | null; avatarUrl: string | null } }) | null loadingAppointmentPlan: boolean } const AppointmentCardCreatorBlock: React.FC = ({ - creator, appointmentPlan, loadingAppointmentPlan, }) => { @@ -150,13 +147,13 @@ const AppointmentCardCreatorBlock: React.FC =
- {creator.name} + {appointmentPlan?.creator.name} {formatMessage(appointmentMessages.AppointmentCard.periodDurationAtMost, { duration: appointmentPlan?.duration, @@ -183,10 +180,10 @@ const AppointmentCard: React.VFC = ({ onRefetch, form, }) => { + const apolloClient = useApolloClient() const { id: appId, enabledModules } = useApp() const { formatMessage } = useIntl() - const { authToken, currentMemberId } = useAuth() - const apolloClient = useApolloClient() + const { authToken, currentMemberId, currentMember } = useAuth() const [issueModalVisible, setIssueModalVisible] = useState(false) const [cancelModalVisible, setCancelModalVisible] = useState(false) const [rescheduleModalVisible, setRescheduleModalVisible] = useState(false) @@ -198,18 +195,16 @@ const AppointmentCard: React.VFC = ({ appointmentPlanId: string }>() const [loading, setLoading] = useState(false) + const [confirm, setConfirm] = useState(false) + const { loading: loadingServices, services } = useService() const { loading: loadingOrderProduct, orderProduct, refetchOrderProduct } = useOrderProduct(orderProductId) - const { loading: loadingAppointmentPlanPreview, appointmentPlanPreview } = - useAppointmentPlanPreview(appointmentPlanId) const { loadingAppointmentPlan, appointmentPlan, refetchAppointmentPlan } = useAppointmentPlan( appointmentPlanId, - memberId || '', + memberId, ) - const { loading: loadingCreator, creator } = useCreator(appointmentPlanPreview.creatorId) const updateAppointmentIssue = useUpdateAppointmentIssue(orderProductId, orderProduct.options) const cancelAppointment = useCancelAppointment(orderProductId, orderProduct.options) const updateAppointmentPeriod = useUpdateAppointmentPeriod(orderProductId, orderProduct.options) - const [confirm, setConfirm] = useState(false) const handleSubmit = () => { form.validateFields((errors, values) => { @@ -251,7 +246,7 @@ const AppointmentCard: React.VFC = ({ orderProduct.startedAt, currentMemberId || '', ) - onRefetch && onRefetch() + onRefetch?.() await refetchAppointmentPlan() setRescheduleModalVisible(false) handleRescheduleCancel() @@ -267,7 +262,7 @@ const AppointmentCard: React.VFC = ({ ) } } catch (error) { - console.log(error) + if (process.env.NODE_ENV === 'development') console.log(error) } } @@ -280,6 +275,59 @@ const AppointmentCard: React.VFC = ({ }) } + const handleAttend = async () => { + let joinUrl + if (!currentMemberId) return message.error('無法獲取當前使用者 id') + if (!appointmentPlan) return message.error('無法獲取當前預約方案資訊') + if (!appointmentPlan.creator) return message.error('無法獲取當前方案的主持者資訊') + const { data } = await apolloClient.query< + hasura.GetMeetByTargetAndPeriod, + hasura.GetMeetByTargetAndPeriodVariables + >({ + query: GetMeetByTargetAndPeriod, + variables: { + appId, + target: appointmentPlanId, + startedAt: orderProduct.startedAt, + endedAt: orderProduct.endedAt, + memberId: currentMemberId, + }, + }) + if (data.meet.length !== 0 && data.meet[0].options?.joinUrl) { + joinUrl = data.meet[0].options.joinUrl + } else if (enabledModules.meet_service && appointmentPlan.defaultMeetGateway === 'zoom') { + // create zoom meeting than get joinUrl + try { + const { data: createMeetData } = await axios.post( + `${process.env.REACT_APP_KOLABLE_SERVER_ENDPOINT}/kolable/meets`, + { + memberId: currentMemberId, + startedAt: orderProduct.startedAt, + endedAt: orderProduct.endedAt, + autoRecording: true, + nbfAt: orderProduct.startedAt, + expAt: orderProduct.endedAt, + service: 'zoom', + target: appointmentPlanId, + hostMemberId: appointmentPlan.creator.id, + type: 'appointmentPlan', + }, + { + headers: { + authorization: `Bearer ${authToken}`, + }, + }, + ) + joinUrl = createMeetData.data?.options?.joinUrl + } catch (error) { + handleError(error) + } + } else { + joinUrl = `https://meet.jit.si/${orderProductId}#config.startWithVideoMuted=true&userInfo.displayName="${currentMember?.name}", '_blank', 'noopener=yes,noreferrer=yes'` + } + if (joinUrl) window.open(joinUrl) + } + if (loadingOrderProduct) { return ( @@ -295,18 +343,23 @@ const AppointmentCard: React.VFC = ({
- {loadingCreator ? ( + {loadingAppointmentPlan ? ( - ) : ( - - )} + ) : appointmentPlan?.creator ? ( + + ) : null}
- {loadingAppointmentPlanPreview ? ( + {loadingAppointmentPlan ? ( - ) : ( - {appointmentPlanPreview.title} - )} + ) : appointmentPlan ? ( + {appointmentPlan.title} + ) : null}
@@ -322,7 +375,13 @@ const AppointmentCard: React.VFC = ({
- {loadingCreator ? : creator.name} + + {loadingAppointmentPlan ? ( + + ) : appointmentPlan?.creator ? ( + appointmentPlan.creator.name + ) : null} +
@@ -346,7 +405,7 @@ const AppointmentCard: React.VFC = ({ ) : isFinished ? ( {formatMessage(appointmentMessages['*'].finished)} - ) : ( + ) : appointmentPlan ? ( <> - {loadingAppointmentPlanPreview ? ( + {loadingAppointmentPlan ? ( - ) : !orderProduct.options?.joinUrl && appointmentPlanPreview.meetGenerationMethod === 'manual' ? ( + ) : !orderProduct.options?.joinUrl && appointmentPlan.meetGenerationMethod === 'manual' ? ( 尚未設定連結 - ) : ( + ) : // dayjs(orderProduct.startedAt).diff(new Date(), 'minute') > 10 ? ( + // 會議尚未開始 + // ) : + currentMember ? ( - )} + ) : null} - {appointmentPlan?.rescheduleAmount !== -1 && ( + {/* {appointmentPlan?.rescheduleAmount !== -1 && ( setRescheduleModalVisible(true)}> {formatMessage(appointmentMessages.AppointmentCard.rescheduleAppointment)} - )} + )} */} setCancelModalVisible(true)}> {formatMessage(appointmentMessages.AppointmentCard.cancelAppointment)} @@ -442,7 +461,7 @@ const AppointmentCard: React.VFC = ({ - )} + ) : null} {/* issue modal */} @@ -546,7 +565,6 @@ const AppointmentCard: React.VFC = ({ onCancel={() => setRescheduleModalVisible(false)} > @@ -560,12 +578,22 @@ const AppointmentCard: React.VFC = ({
{moment(period.startedAt).format('YYYY-MM-DD(dd)')} - !period.currentMemberBooked && !period.isBookedReachLimit && !period.available + !period.currentMemberBooked && !period.isBookedReachLimit && period.available ? setRescheduleAppointment({ rescheduleAppointment: true, periodStartedAt: period.startedAt, @@ -595,7 +623,6 @@ const AppointmentCard: React.VFC = ({ onCancel={handleRescheduleCancel} > @@ -681,37 +708,6 @@ const AppointmentCard: React.VFC = ({ export default Form.create()(AppointmentCard) -export const useAppointmentPlanPreview = (appointmentPlanId: string) => { - const { loading, data } = useQuery( - gql` - query GetAppointmentPlanPreview($appointmentPlanId: uuid!) { - appointment_plan_by_pk(id: $appointmentPlanId) { - id - title - creator_id - meet_generation_method - } - } - `, - { variables: { appointmentPlanId } }, - ) - const appointmentPlanPreview: { - id: string - title: string - creatorId: string - meetGenerationMethod: string - } = { - id: data?.appointment_plan_by_pk?.id, - title: data?.appointment_plan_by_pk?.title || '', - creatorId: data?.appointment_plan_by_pk?.creator_id || '', - meetGenerationMethod: data?.appointment_plan_by_pk?.meet_generation_method || 'auto', - } - return { - loading, - appointmentPlanPreview, - } -} - const useUpdateAppointmentPeriod = (orderProductId: string, options: { rescheduleLog: [] }) => { const [updateAppointmentPeriod] = useMutation< hasura.UpdateAppointmentPeriod, @@ -809,26 +805,3 @@ export const useOrderProduct = (orderProductId: string) => { refetchOrderProduct: refetch, } } - -export const useCreator = (creatorId: string) => { - const { loading, data } = useQuery( - gql` - query GetCreatorInfo($creatorId: String) { - member_public(where: { id: { _eq: $creatorId } }) { - id - picture_url - name - } - } - `, - { variables: { creatorId } }, - ) - const creator: { avatarUrl: string | null; name: string } = { - avatarUrl: data?.member_public?.[0]?.picture_url || '', - name: data?.member_public?.[0]?.name || '', - } - return { - loading, - creator, - } -} diff --git a/src/components/appointment/AppointmentCollectionTabs.tsx b/src/components/appointment/AppointmentCollectionTabs.tsx index d3ea8ccd9..f7d489df9 100644 --- a/src/components/appointment/AppointmentCollectionTabs.tsx +++ b/src/components/appointment/AppointmentCollectionTabs.tsx @@ -69,8 +69,9 @@ const StyledTimeStandardBlock = styled.div` ` const AppointmentCollectionTabs: React.VFC<{ + creatorId: string appointmentPlans: (AppointmentPlan & { periods: AppointmentPeriod[] })[] -}> = ({ appointmentPlans }) => { +}> = ({ creatorId, appointmentPlans }) => { const { formatMessage } = useIntl() const [selectedAppointmentPlanId, setSelectedAppointmentPlanId] = useState(appointmentPlans[0].id) const { search } = useLocation() @@ -145,6 +146,7 @@ const AppointmentCollectionTabs: React.VFC<{
appointmentPlanId ? v.id === appointmentPlanId || v.isPrivate === false : v.isPrivate === false, @@ -158,8 +160,9 @@ const AppointmentCollectionTabs: React.VFC<{ } export const AppointmentPlanCollection: React.FC<{ + creatorId: string appointmentPlans: (AppointmentPlan & { periods: AppointmentPeriod[] })[] -}> = ({ appointmentPlans }) => { +}> = ({ creatorId, appointmentPlans }) => { const { formatMessage } = useIntl() const { id: appId } = useApp() const { isAuthenticated } = useAuth() @@ -168,14 +171,6 @@ export const AppointmentPlanCollection: React.FC<{ const [selectedPeriod, setSelectedPeriod] = useState(null) - const diffPlanBookedTimes = [ - ...appointmentPlans.map(appointmentPlan => - appointmentPlan.periods - .filter(period => Boolean(period.booked >= appointmentPlan.capacity && appointmentPlan.capacity !== -1)) - .map(v => moment(v.startedAt).format('YYYY-MM-DD HH:mm')), - ), - ].flat(1) - const { resourceCollection } = useResourceCollection( appId ? appointmentPlans.map(appointmentPlan => `${appId}:appointment_plan:${appointmentPlan.id}`) : [], true, @@ -206,9 +201,15 @@ export const AppointmentPlanCollection: React.FC<{ startedAt={selectedPeriod?.startedAt} renderTrigger={({ setVisible }) => ( { if (!isAuthenticated) { setAuthModalVisible?.(true) @@ -230,7 +231,6 @@ export const AppointmentPlanCollection: React.FC<{ resource && tracking.click(resource, { position: idx + 1 }) } }} - diffPlanBookedTimes={diffPlanBookedTimes} /> )} /> @@ -239,9 +239,15 @@ export const AppointmentPlanCollection: React.FC<{ defaultProductId={`AppointmentPlan_${appointmentPlan.id}`} renderTrigger={({ onOpen }) => ( { if (!isAuthenticated) { setAuthModalVisible?.(true) @@ -263,7 +269,6 @@ export const AppointmentPlanCollection: React.FC<{ resource && tracking.click(resource, { position: idx + 1 }) } }} - diffPlanBookedTimes={diffPlanBookedTimes} /> )} startedAt={selectedPeriod?.startedAt} diff --git a/src/components/appointment/AppointmentItem.tsx b/src/components/appointment/AppointmentItem.tsx index d14c0b908..488902b8e 100644 --- a/src/components/appointment/AppointmentItem.tsx +++ b/src/components/appointment/AppointmentItem.tsx @@ -1,22 +1,31 @@ +import { Spinner } from '@chakra-ui/react' +import { uniq } from 'ramda' import React from 'react' import { useIntl } from 'react-intl' import styled, { css } from 'styled-components' -import { productMessages } from '../../helpers/translation' +import { useMeetByAppointmentPlanIdAndPeriod } from '../../hooks/appointment' +import { useOverlapMeets } from '../../hooks/meet' +import appointmentMessages from './translation' -const StyledItemWrapper = styled.div<{ variant?: 'default' | 'excluded' | 'disabled' }>` +const StyledItemWrapper = styled.div<{ + variant?: 'bookable' | 'closed' | 'booked' | 'meetingFull' +}>` position: relative; margin-bottom: 0.5rem; margin-right: 0.5rem; padding: 0.75rem; width: 6rem; overflow: hidden; - border: solid 1px ${props => (props.variant === 'disabled' ? 'var(--gray-light)' : 'var(--gray-dark)')}; - color: ${props => (props.variant === 'disabled' ? 'var(--gray-dark)' : 'var(--gray-darker)')}; + border: solid 1px + ${props => + props.variant === 'booked' || props.variant === 'meetingFull' ? 'var(--gray-light)' : 'var(--gray-dark)'}; + color: ${props => + props.variant === 'booked' || props.variant === 'meetingFull' ? 'var(--gray-dark)' : 'var(--gray-darker)'}; border-radius: 4px; - cursor: ${props => (props.variant !== 'default' ? 'not-allowed' : 'pointer')}; + cursor: ${props => (props.variant !== 'bookable' ? 'not-allowed' : 'pointer')}; ${props => - props.variant === 'excluded' + props.variant === 'closed' ? css` ::before { display: block; @@ -46,28 +55,117 @@ const StyledItemMeta = styled.div` ` const AppointmentItem: React.VFC<{ - id: string - startedAt: Date + creatorId: string + appointmentPlan: { + id: string + capacity: number + defaultMeetGateway: string + } + period: { + startedAt: Date + endedAt: Date + } + services: { id: string; gateway: string }[] + loadingServices?: boolean + isPeriodExcluded?: boolean isEnrolled?: boolean - isExcluded?: boolean + overLapPeriods?: string[] onClick: () => void -}> = ({ startedAt, isEnrolled, isExcluded, onClick }) => { + onOverlapPeriodsChange?: (overLapPeriods: string[]) => void +}> = ({ + creatorId, + appointmentPlan, + period, + services, + loadingServices, + isPeriodExcluded, + isEnrolled, + overLapPeriods, + onClick, + onOverlapPeriodsChange, +}) => { const { formatMessage } = useIntl() - - return ( - - - {startedAt.getHours().toString().padStart(2, '0')}:{startedAt.getMinutes().toString().padStart(2, '0')} - - - {isEnrolled - ? formatMessage(productMessages.appointment.status.booked) - : isExcluded - ? formatMessage(productMessages.appointment.status.closed) - : formatMessage(productMessages.appointment.status.bookable)} - - + const { loading: loadingMeetMembers, meet } = useMeetByAppointmentPlanIdAndPeriod( + appointmentPlan.id, + period.startedAt, + period.endedAt, ) + const { loading: loadingOverlapMeet, overlapMeets } = useOverlapMeets(period.startedAt, period.endedAt) + const zoomServices = services.filter(service => service.gateway === 'zoom').map(service => service.id) + const overlapCreatorMeets = overlapMeets + .filter(overlapMeet => overlapMeet.hostMemberId === creatorId) + .filter(overlapCreatorMeet => overlapCreatorMeet.target !== appointmentPlan.id) + const currentUseServices = uniq(overlapMeets.map(overlapMeet => overlapMeet.serviceId)) + + let variant: 'bookable' | 'closed' | 'booked' | 'meetingFull' | 'overlap' | undefined + + if (overlapCreatorMeets.length >= 1) + overLapPeriods && + !overLapPeriods.some(overLapPeriod => overLapPeriod === appointmentPlan.id) && + onOverlapPeriodsChange?.([...overLapPeriods, appointmentPlan.id]) + + if (isPeriodExcluded) { + variant = 'closed' + } else if (isEnrolled) { + variant = 'booked' + } else if (overlapCreatorMeets.length >= 1) { + variant = 'overlap' + } else { + if (appointmentPlan.defaultMeetGateway === 'zoom') { + if ( + zoomServices.length >= 1 && + zoomServices.filter(zoomService => !currentUseServices.includes(zoomService)).length >= 1 + ) { + if (appointmentPlan.capacity === -1) { + variant = 'bookable' + } else { + if (meet) { + meet.meetMembers.length >= appointmentPlan.capacity ? (variant = 'meetingFull') : (variant = 'bookable') + } else { + variant = 'bookable' + } + } + } else { + variant = 'meetingFull' + } + } else { + if (appointmentPlan.capacity === -1) { + variant = 'bookable' + } else { + if (meet) { + meet.meetMembers.length >= appointmentPlan.capacity ? (variant = 'meetingFull') : (variant = 'bookable') + } else { + variant = 'bookable' + } + } + } + } + + if (variant === 'overlap') { + return null + } else { + return ( + + + {period.startedAt.getHours().toString().padStart(2, '0')}: + {period.startedAt.getMinutes().toString().padStart(2, '0')} + + + {loadingMeetMembers || loadingOverlapMeet || loadingServices ? ( + + ) : variant === 'booked' ? ( + formatMessage(appointmentMessages.AppointmentItem.booked) + ) : variant === 'meetingFull' ? ( + formatMessage(appointmentMessages.AppointmentItem.meetingIsFull) + ) : variant === 'bookable' ? ( + formatMessage(appointmentMessages.AppointmentItem.bookable) + ) : ( + formatMessage(appointmentMessages.AppointmentItem.closed) + )} + + + ) + } } export default AppointmentItem diff --git a/src/components/appointment/AppointmentPeriodCollection.tsx b/src/components/appointment/AppointmentPeriodCollection.tsx index 50183c369..e7184095f 100644 --- a/src/components/appointment/AppointmentPeriodCollection.tsx +++ b/src/components/appointment/AppointmentPeriodCollection.tsx @@ -1,8 +1,10 @@ import { useAuth } from 'lodestar-app-element/src/contexts/AuthContext' import moment from 'moment' +import dayjs from 'dayjs' import { groupBy } from 'ramda' -import React, { useContext } from 'react' +import React, { useContext, useState } from 'react' import styled from 'styled-components' +import { useService } from '../../hooks/service' import { AppointmentPeriod, ReservationType } from '../../types/appointment' import { AuthModalContext } from '../auth/AuthModal' import AppointmentItem from './AppointmentItem' @@ -15,78 +17,110 @@ const StyledScheduleTitle = styled.h3` letter-spacing: 0.2px; color: var(--gray-darker); ` - -const AppointmentPeriodCollection: React.VFC<{ - appointmentPeriods: AppointmentPeriod[] - reservationType?: ReservationType - reservationAmount?: number - diffPlanBookedTimes?: String[] +const AppointmentPeriodBlock: React.VFC<{ + periods: AppointmentPeriod[] + creatorId: string + appointmentPlan: { + id: string + defaultMeetGateway: string + reservationType: ReservationType + reservationAmount: number + capacity: number + } onClick: (period: AppointmentPeriod) => void -}> = ({ appointmentPeriods, reservationType, reservationAmount, diffPlanBookedTimes, onClick }) => { +}> = ({ periods, creatorId, appointmentPlan, onClick }) => { const { setVisible: setAuthModalVisible } = useContext(AuthModalContext) const { isAuthenticated } = useAuth() + const { loading: loadingServices, services } = useService() + const [overLapPeriods, setOverLapPeriods] = useState([]) + return ( +
+ {overLapPeriods.length !== periods.length ? ( + {moment(periods[0].startedAt).format('YYYY-MM-DD(dd)')} + ) : null} +
+ {periods.map(period => { + const ItemElem = ( + + !period.currentMemberBooked && !period.isBookedReachLimit && !period.available ? onClick(period) : null + } + overLapPeriods={overLapPeriods} + onOverlapPeriodsChange={setOverLapPeriods} + /> + ) + + return isAuthenticated && !period.currentMemberBooked ? ( +
onClick && onClick(period)}> + {ItemElem} +
+ ) : isAuthenticated && period.currentMemberBooked ? ( +
{ + return + }} + > + {ItemElem} +
+ ) : ( +
setAuthModalVisible && setAuthModalVisible(true)}> + {ItemElem} +
+ ) + })} +
+
+ ) +} + +const AppointmentPeriodCollection: React.VFC<{ + creatorId: string + appointmentPlan: { + id: string + defaultMeetGateway: string + reservationType: ReservationType + reservationAmount: number + capacity: number + } + appointmentPeriods: AppointmentPeriod[] + onClick: (period: AppointmentPeriod) => void +}> = ({ creatorId, appointmentPlan, appointmentPeriods, onClick }) => { const periods = groupBy( - period => moment(period.startedAt).format('YYYY-MM-DD(dd)'), - appointmentPeriods - .filter(v => v.available) - .filter( - v => - !diffPlanBookedTimes?.some( - diffPlanBookedTime => moment(v.startedAt).format('YYYY-MM-DD HH:mm').toString() === diffPlanBookedTime, - ), - ) - .filter(v => - reservationType && reservationAmount && reservationAmount !== 0 - ? moment(v.startedAt).subtract(reservationType, reservationAmount).toDate() > moment().toDate() - : v, - ), + period => dayjs(period.startedAt).format('YYYY-MM-DD(dd)'), + appointmentPeriods.filter(v => + appointmentPlan.reservationType && appointmentPlan.reservationAmount && appointmentPlan.reservationAmount !== 0 + ? dayjs(v.startedAt).subtract(appointmentPlan.reservationAmount, appointmentPlan.reservationType).toDate() > + dayjs().toDate() + : v, + ), ) return ( <> {Object.values(periods).map(periods => ( -
- {moment(periods[0].startedAt).format('YYYY-MM-DD(dd)')} - -
- {periods.map(period => { - const ItemElem = ( - - !period.currentMemberBooked && !period.isBookedReachLimit && !period.available - ? onClick(period) - : null - } - /> - ) - - return isAuthenticated && !period.currentMemberBooked ? ( -
onClick && onClick(period)}> - {ItemElem} -
- ) : isAuthenticated && period.currentMemberBooked ? ( -
{ - return - }} - > - {ItemElem} -
- ) : ( -
setAuthModalVisible && setAuthModalVisible(true)}> - {ItemElem} -
- ) - })} -
-
+ ))} ) diff --git a/src/components/appointment/translation.tsx b/src/components/appointment/translation.tsx index b84afddd4..bf297c69f 100644 --- a/src/components/appointment/translation.tsx +++ b/src/components/appointment/translation.tsx @@ -71,6 +71,12 @@ const appointmentMessages = { defaultMessage: '時間以 {city} (GMT{timezone}) 顯示', }, }), + AppointmentItem: defineMessages({ + booked: { id: 'appointment.AppointmentItem.booked', defaultMessage: '已預約' }, + bookable: { id: 'appointment.AppointmentItem.bookable', defaultMessage: '可預約' }, + meetingIsFull: { id: 'appointment.AppointmentItem.meetingIsFull', defaultMessage: '已無會議室' }, + closed: { id: 'appointment.AppointmentItem.closed', defaultMessage: '已關閉' }, + }), } export default appointmentMessages diff --git a/src/components/coin/AppointmentCoinModal.tsx b/src/components/coin/AppointmentCoinModal.tsx index c2560ef66..dafc435ea 100644 --- a/src/components/coin/AppointmentCoinModal.tsx +++ b/src/components/coin/AppointmentCoinModal.tsx @@ -66,7 +66,6 @@ const AppointmentCoinModal: React.VFC< const history = useHistory() const { currentMember } = useAuth() const { loadingAppointmentPlan, appointmentPlan } = useAppointmentPlan(appointmentPlanId) - const phoneInputRef = useRef(null) const [visible, setVisible] = useState(false) const [selectedPeriod, setSelectedPeriod] = useState(null) @@ -186,6 +185,14 @@ const AppointmentCoinModal: React.VFC< ) : ( moment(period.startedAt) > moment().endOf('isoWeek'), )} diff --git a/src/containers/common/AuthButton.tsx b/src/containers/common/AuthButton.tsx index 4b1941fdc..99130160f 100644 --- a/src/containers/common/AuthButton.tsx +++ b/src/containers/common/AuthButton.tsx @@ -16,6 +16,7 @@ const AuthButton: React.VFC = () => { const handleClick = () => { authModal.open(setVisible) + window.history.pushState(null, '', '#') } return ( diff --git a/src/hasura.d.ts b/src/hasura.d.ts index 146d10ac1..9b09f6d0e 100644 --- a/src/hasura.d.ts +++ b/src/hasura.d.ts @@ -5558,6 +5558,8 @@ export type app_channel = { /** An object relationship */ app: app; app_id: Scalars['String']; + /** 通路代號 */ + code?: Maybe; id: Scalars['uuid']; name: Scalars['String']; /** An array relationship */ @@ -5615,6 +5617,7 @@ export type app_channel_bool_exp = { _or?: InputMaybe>; app?: InputMaybe; app_id?: InputMaybe; + code?: InputMaybe; id?: InputMaybe; name?: InputMaybe; product_channels?: InputMaybe; @@ -5631,6 +5634,8 @@ export enum app_channel_constraint { export type app_channel_insert_input = { app?: InputMaybe; app_id?: InputMaybe; + /** 通路代號 */ + code?: InputMaybe; id?: InputMaybe; name?: InputMaybe; product_channels?: InputMaybe; @@ -5640,6 +5645,8 @@ export type app_channel_insert_input = { export type app_channel_max_fields = { __typename?: 'app_channel_max_fields'; app_id?: Maybe; + /** 通路代號 */ + code?: Maybe; id?: Maybe; name?: Maybe; }; @@ -5648,6 +5655,8 @@ export type app_channel_max_fields = { export type app_channel_min_fields = { __typename?: 'app_channel_min_fields'; app_id?: Maybe; + /** 通路代號 */ + code?: Maybe; id?: Maybe; name?: Maybe; }; @@ -5679,6 +5688,7 @@ export type app_channel_on_conflict = { export type app_channel_order_by = { app?: InputMaybe; app_id?: InputMaybe; + code?: InputMaybe; id?: InputMaybe; name?: InputMaybe; product_channels_aggregate?: InputMaybe; @@ -5694,6 +5704,8 @@ export enum app_channel_select_column { /** column name */ app_id = 'app_id', /** column name */ + code = 'code', + /** column name */ id = 'id', /** column name */ name = 'name' @@ -5702,6 +5714,8 @@ export enum app_channel_select_column { /** input type for updating data in table "app_channel" */ export type app_channel_set_input = { app_id?: InputMaybe; + /** 通路代號 */ + code?: InputMaybe; id?: InputMaybe; name?: InputMaybe; }; @@ -5717,6 +5731,8 @@ export type app_channel_stream_cursor_input = { /** Initial value of the column from where the streaming should start */ export type app_channel_stream_cursor_value_input = { app_id?: InputMaybe; + /** 通路代號 */ + code?: InputMaybe; id?: InputMaybe; name?: InputMaybe; }; @@ -5726,6 +5742,8 @@ export enum app_channel_update_column { /** column name */ app_id = 'app_id', /** column name */ + code = 'code', + /** column name */ id = 'id', /** column name */ name = 'name' @@ -11242,7 +11260,7 @@ export type appointment_plan = { currency: currency; currency_id: Scalars['String']; /** jitsi, zoom */ - default_meet_system: Scalars['String']; + default_meet_gateway: Scalars['String']; description?: Maybe; /** minutes */ duration: Scalars['numeric']; @@ -11456,7 +11474,7 @@ export type appointment_plan_bool_exp = { creator_id?: InputMaybe; currency?: InputMaybe; currency_id?: InputMaybe; - default_meet_system?: InputMaybe; + default_meet_gateway?: InputMaybe; description?: InputMaybe; duration?: InputMaybe; id?: InputMaybe; @@ -11600,7 +11618,7 @@ export type appointment_plan_insert_input = { currency?: InputMaybe; currency_id?: InputMaybe; /** jitsi, zoom */ - default_meet_system?: InputMaybe; + default_meet_gateway?: InputMaybe; description?: InputMaybe; /** minutes */ duration?: InputMaybe; @@ -11631,7 +11649,7 @@ export type appointment_plan_max_fields = { creator_id?: Maybe; currency_id?: Maybe; /** jitsi, zoom */ - default_meet_system?: Maybe; + default_meet_gateway?: Maybe; description?: Maybe; /** minutes */ duration?: Maybe; @@ -11659,7 +11677,7 @@ export type appointment_plan_max_order_by = { creator_id?: InputMaybe; currency_id?: InputMaybe; /** jitsi, zoom */ - default_meet_system?: InputMaybe; + default_meet_gateway?: InputMaybe; description?: InputMaybe; /** minutes */ duration?: InputMaybe; @@ -11688,7 +11706,7 @@ export type appointment_plan_min_fields = { creator_id?: Maybe; currency_id?: Maybe; /** jitsi, zoom */ - default_meet_system?: Maybe; + default_meet_gateway?: Maybe; description?: Maybe; /** minutes */ duration?: Maybe; @@ -11716,7 +11734,7 @@ export type appointment_plan_min_order_by = { creator_id?: InputMaybe; currency_id?: InputMaybe; /** jitsi, zoom */ - default_meet_system?: InputMaybe; + default_meet_gateway?: InputMaybe; description?: InputMaybe; /** minutes */ duration?: InputMaybe; @@ -11770,7 +11788,7 @@ export type appointment_plan_order_by = { creator_id?: InputMaybe; currency?: InputMaybe; currency_id?: InputMaybe; - default_meet_system?: InputMaybe; + default_meet_gateway?: InputMaybe; description?: InputMaybe; duration?: InputMaybe; id?: InputMaybe; @@ -11809,7 +11827,7 @@ export enum appointment_plan_select_column { /** column name */ currency_id = 'currency_id', /** column name */ - default_meet_system = 'default_meet_system', + default_meet_gateway = 'default_meet_gateway', /** column name */ description = 'description', /** column name */ @@ -11862,7 +11880,7 @@ export type appointment_plan_set_input = { creator_id?: InputMaybe; currency_id?: InputMaybe; /** jitsi, zoom */ - default_meet_system?: InputMaybe; + default_meet_gateway?: InputMaybe; description?: InputMaybe; /** minutes */ duration?: InputMaybe; @@ -11975,7 +11993,7 @@ export type appointment_plan_stream_cursor_value_input = { creator_id?: InputMaybe; currency_id?: InputMaybe; /** jitsi, zoom */ - default_meet_system?: InputMaybe; + default_meet_gateway?: InputMaybe; description?: InputMaybe; /** minutes */ duration?: InputMaybe; @@ -12033,7 +12051,7 @@ export enum appointment_plan_update_column { /** column name */ currency_id = 'currency_id', /** column name */ - default_meet_system = 'default_meet_system', + default_meet_gateway = 'default_meet_gateway', /** column name */ description = 'description', /** column name */ @@ -30831,12 +30849,20 @@ export type meet = { app_id: Scalars['String']; auto_recording: Scalars['Boolean']; created_at: Scalars['timestamptz']; + deleted_at?: Maybe; ended_at: Scalars['timestamptz']; exp_at?: Maybe; + /** jitsi, zoom */ + gateway: Scalars['String']; + host_member_id: Scalars['String']; id: Scalars['uuid']; - member_id: Scalars['String']; + /** An array relationship */ + meet_members: Array; + /** An aggregate relationship */ + meet_members_aggregate: meet_member_aggregate; nbf_at?: Maybe; options: Scalars['jsonb']; + service_id?: Maybe; started_at: Scalars['timestamptz']; /** appointment_plan_id, member_task_id */ target: Scalars['uuid']; @@ -30845,6 +30871,26 @@ export type meet = { }; +/** columns and relationships of "meet" */ +export type meetmeet_membersArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +/** columns and relationships of "meet" */ +export type meetmeet_members_aggregateArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + /** columns and relationships of "meet" */ export type meetoptionsArgs = { path?: InputMaybe; @@ -30885,12 +30931,17 @@ export type meet_bool_exp = { app_id?: InputMaybe; auto_recording?: InputMaybe; created_at?: InputMaybe; + deleted_at?: InputMaybe; ended_at?: InputMaybe; exp_at?: InputMaybe; + gateway?: InputMaybe; + host_member_id?: InputMaybe; id?: InputMaybe; - member_id?: InputMaybe; + meet_members?: InputMaybe; + meet_members_aggregate?: InputMaybe; nbf_at?: InputMaybe; options?: InputMaybe; + service_id?: InputMaybe; started_at?: InputMaybe; target?: InputMaybe; type?: InputMaybe; @@ -30923,12 +30974,17 @@ export type meet_insert_input = { app_id?: InputMaybe; auto_recording?: InputMaybe; created_at?: InputMaybe; + deleted_at?: InputMaybe; ended_at?: InputMaybe; exp_at?: InputMaybe; + /** jitsi, zoom */ + gateway?: InputMaybe; + host_member_id?: InputMaybe; id?: InputMaybe; - member_id?: InputMaybe; + meet_members?: InputMaybe; nbf_at?: InputMaybe; options?: InputMaybe; + service_id?: InputMaybe; started_at?: InputMaybe; /** appointment_plan_id, member_task_id */ target?: InputMaybe; @@ -30941,11 +30997,15 @@ export type meet_max_fields = { __typename?: 'meet_max_fields'; app_id?: Maybe; created_at?: Maybe; + deleted_at?: Maybe; ended_at?: Maybe; exp_at?: Maybe; + /** jitsi, zoom */ + gateway?: Maybe; + host_member_id?: Maybe; id?: Maybe; - member_id?: Maybe; nbf_at?: Maybe; + service_id?: Maybe; started_at?: Maybe; /** appointment_plan_id, member_task_id */ target?: Maybe; @@ -30953,16 +31013,254 @@ export type meet_max_fields = { updated_at?: Maybe; }; +/** meet participants */ +export type meet_member = { + __typename?: 'meet_member'; + created_at: Scalars['timestamptz']; + deleted_at?: Maybe; + id: Scalars['uuid']; + /** An object relationship */ + meet?: Maybe; + meet_id: Scalars['uuid']; + member_id: Scalars['String']; + updated_at: Scalars['timestamptz']; +}; + +/** aggregated selection of "meet_member" */ +export type meet_member_aggregate = { + __typename?: 'meet_member_aggregate'; + aggregate?: Maybe; + nodes: Array; +}; + +export type meet_member_aggregate_bool_exp = { + count?: InputMaybe; +}; + +export type meet_member_aggregate_bool_exp_count = { + arguments?: InputMaybe>; + distinct?: InputMaybe; + filter?: InputMaybe; + predicate: Int_comparison_exp; +}; + +/** aggregate fields of "meet_member" */ +export type meet_member_aggregate_fields = { + __typename?: 'meet_member_aggregate_fields'; + count: Scalars['Int']; + max?: Maybe; + min?: Maybe; +}; + + +/** aggregate fields of "meet_member" */ +export type meet_member_aggregate_fieldscountArgs = { + columns?: InputMaybe>; + distinct?: InputMaybe; +}; + +/** order by aggregate values of table "meet_member" */ +export type meet_member_aggregate_order_by = { + count?: InputMaybe; + max?: InputMaybe; + min?: InputMaybe; +}; + +/** input type for inserting array relation for remote table "meet_member" */ +export type meet_member_arr_rel_insert_input = { + data: Array; + /** upsert condition */ + on_conflict?: InputMaybe; +}; + +/** Boolean expression to filter rows from the table "meet_member". All fields are combined with a logical 'AND'. */ +export type meet_member_bool_exp = { + _and?: InputMaybe>; + _not?: InputMaybe; + _or?: InputMaybe>; + created_at?: InputMaybe; + deleted_at?: InputMaybe; + id?: InputMaybe; + meet?: InputMaybe; + meet_id?: InputMaybe; + member_id?: InputMaybe; + updated_at?: InputMaybe; +}; + +/** unique or primary key constraints on table "meet_member" */ +export enum meet_member_constraint { + /** unique or primary key constraint on columns "member_id", "meet_id" */ + meet_member_meet_id_member_id_key = 'meet_member_meet_id_member_id_key', + /** unique or primary key constraint on columns "id" */ + meet_member_pkey = 'meet_member_pkey' +} + +/** input type for inserting data into table "meet_member" */ +export type meet_member_insert_input = { + created_at?: InputMaybe; + deleted_at?: InputMaybe; + id?: InputMaybe; + meet?: InputMaybe; + meet_id?: InputMaybe; + member_id?: InputMaybe; + updated_at?: InputMaybe; +}; + +/** aggregate max on columns */ +export type meet_member_max_fields = { + __typename?: 'meet_member_max_fields'; + created_at?: Maybe; + deleted_at?: Maybe; + id?: Maybe; + meet_id?: Maybe; + member_id?: Maybe; + updated_at?: Maybe; +}; + +/** order by max() on columns of table "meet_member" */ +export type meet_member_max_order_by = { + created_at?: InputMaybe; + deleted_at?: InputMaybe; + id?: InputMaybe; + meet_id?: InputMaybe; + member_id?: InputMaybe; + updated_at?: InputMaybe; +}; + +/** aggregate min on columns */ +export type meet_member_min_fields = { + __typename?: 'meet_member_min_fields'; + created_at?: Maybe; + deleted_at?: Maybe; + id?: Maybe; + meet_id?: Maybe; + member_id?: Maybe; + updated_at?: Maybe; +}; + +/** order by min() on columns of table "meet_member" */ +export type meet_member_min_order_by = { + created_at?: InputMaybe; + deleted_at?: InputMaybe; + id?: InputMaybe; + meet_id?: InputMaybe; + member_id?: InputMaybe; + updated_at?: InputMaybe; +}; + +/** response of any mutation on the table "meet_member" */ +export type meet_member_mutation_response = { + __typename?: 'meet_member_mutation_response'; + /** number of rows affected by the mutation */ + affected_rows: Scalars['Int']; + /** data from the rows affected by the mutation */ + returning: Array; +}; + +/** on_conflict condition type for table "meet_member" */ +export type meet_member_on_conflict = { + constraint: meet_member_constraint; + update_columns?: Array; + where?: InputMaybe; +}; + +/** Ordering options when selecting data from "meet_member". */ +export type meet_member_order_by = { + created_at?: InputMaybe; + deleted_at?: InputMaybe; + id?: InputMaybe; + meet?: InputMaybe; + meet_id?: InputMaybe; + member_id?: InputMaybe; + updated_at?: InputMaybe; +}; + +/** primary key columns input for table: meet_member */ +export type meet_member_pk_columns_input = { + id: Scalars['uuid']; +}; + +/** select columns of table "meet_member" */ +export enum meet_member_select_column { + /** column name */ + created_at = 'created_at', + /** column name */ + deleted_at = 'deleted_at', + /** column name */ + id = 'id', + /** column name */ + meet_id = 'meet_id', + /** column name */ + member_id = 'member_id', + /** column name */ + updated_at = 'updated_at' +} + +/** input type for updating data in table "meet_member" */ +export type meet_member_set_input = { + created_at?: InputMaybe; + deleted_at?: InputMaybe; + id?: InputMaybe; + meet_id?: InputMaybe; + member_id?: InputMaybe; + updated_at?: InputMaybe; +}; + +/** Streaming cursor of the table "meet_member" */ +export type meet_member_stream_cursor_input = { + /** Stream column input with initial value */ + initial_value: meet_member_stream_cursor_value_input; + /** cursor ordering */ + ordering?: InputMaybe; +}; + +/** Initial value of the column from where the streaming should start */ +export type meet_member_stream_cursor_value_input = { + created_at?: InputMaybe; + deleted_at?: InputMaybe; + id?: InputMaybe; + meet_id?: InputMaybe; + member_id?: InputMaybe; + updated_at?: InputMaybe; +}; + +/** update columns of table "meet_member" */ +export enum meet_member_update_column { + /** column name */ + created_at = 'created_at', + /** column name */ + deleted_at = 'deleted_at', + /** column name */ + id = 'id', + /** column name */ + meet_id = 'meet_id', + /** column name */ + member_id = 'member_id', + /** column name */ + updated_at = 'updated_at' +} + +export type meet_member_updates = { + /** sets the columns of the filtered rows to the given values */ + _set?: InputMaybe; + /** filter the rows which have to be updated */ + where: meet_member_bool_exp; +}; + /** aggregate min on columns */ export type meet_min_fields = { __typename?: 'meet_min_fields'; app_id?: Maybe; created_at?: Maybe; + deleted_at?: Maybe; ended_at?: Maybe; exp_at?: Maybe; + /** jitsi, zoom */ + gateway?: Maybe; + host_member_id?: Maybe; id?: Maybe; - member_id?: Maybe; nbf_at?: Maybe; + service_id?: Maybe; started_at?: Maybe; /** appointment_plan_id, member_task_id */ target?: Maybe; @@ -30998,12 +31296,16 @@ export type meet_order_by = { app_id?: InputMaybe; auto_recording?: InputMaybe; created_at?: InputMaybe; + deleted_at?: InputMaybe; ended_at?: InputMaybe; exp_at?: InputMaybe; + gateway?: InputMaybe; + host_member_id?: InputMaybe; id?: InputMaybe; - member_id?: InputMaybe; + meet_members_aggregate?: InputMaybe; nbf_at?: InputMaybe; options?: InputMaybe; + service_id?: InputMaybe; started_at?: InputMaybe; target?: InputMaybe; type?: InputMaybe; @@ -31029,18 +31331,24 @@ export enum meet_select_column { /** column name */ created_at = 'created_at', /** column name */ + deleted_at = 'deleted_at', + /** column name */ ended_at = 'ended_at', /** column name */ exp_at = 'exp_at', /** column name */ - id = 'id', + gateway = 'gateway', /** column name */ - member_id = 'member_id', + host_member_id = 'host_member_id', + /** column name */ + id = 'id', /** column name */ nbf_at = 'nbf_at', /** column name */ options = 'options', /** column name */ + service_id = 'service_id', + /** column name */ started_at = 'started_at', /** column name */ target = 'target', @@ -31055,12 +31363,16 @@ export type meet_set_input = { app_id?: InputMaybe; auto_recording?: InputMaybe; created_at?: InputMaybe; + deleted_at?: InputMaybe; ended_at?: InputMaybe; exp_at?: InputMaybe; + /** jitsi, zoom */ + gateway?: InputMaybe; + host_member_id?: InputMaybe; id?: InputMaybe; - member_id?: InputMaybe; nbf_at?: InputMaybe; options?: InputMaybe; + service_id?: InputMaybe; started_at?: InputMaybe; /** appointment_plan_id, member_task_id */ target?: InputMaybe; @@ -31081,12 +31393,16 @@ export type meet_stream_cursor_value_input = { app_id?: InputMaybe; auto_recording?: InputMaybe; created_at?: InputMaybe; + deleted_at?: InputMaybe; ended_at?: InputMaybe; exp_at?: InputMaybe; + /** jitsi, zoom */ + gateway?: InputMaybe; + host_member_id?: InputMaybe; id?: InputMaybe; - member_id?: InputMaybe; nbf_at?: InputMaybe; options?: InputMaybe; + service_id?: InputMaybe; started_at?: InputMaybe; /** appointment_plan_id, member_task_id */ target?: InputMaybe; @@ -31103,18 +31419,24 @@ export enum meet_update_column { /** column name */ created_at = 'created_at', /** column name */ + deleted_at = 'deleted_at', + /** column name */ ended_at = 'ended_at', /** column name */ exp_at = 'exp_at', /** column name */ - id = 'id', + gateway = 'gateway', /** column name */ - member_id = 'member_id', + host_member_id = 'host_member_id', + /** column name */ + id = 'id', /** column name */ nbf_at = 'nbf_at', /** column name */ options = 'options', /** column name */ + service_id = 'service_id', + /** column name */ started_at = 'started_at', /** column name */ target = 'target', @@ -40695,6 +41017,7 @@ export type member_task = { /** An object relationship */ meet?: Maybe; meet_id?: Maybe; + meeting_gateway?: Maybe; meeting_hours: Scalars['numeric']; /** An object relationship */ member: member; @@ -40815,6 +41138,7 @@ export type member_task_bool_exp = { id?: InputMaybe; meet?: InputMaybe; meet_id?: InputMaybe; + meeting_gateway?: InputMaybe; meeting_hours?: InputMaybe; member?: InputMaybe; member_id?: InputMaybe; @@ -40850,6 +41174,7 @@ export type member_task_insert_input = { id?: InputMaybe; meet?: InputMaybe; meet_id?: InputMaybe; + meeting_gateway?: InputMaybe; meeting_hours?: InputMaybe; member?: InputMaybe; member_id?: InputMaybe; @@ -40872,6 +41197,7 @@ export type member_task_max_fields = { executor_id?: Maybe; id?: Maybe; meet_id?: Maybe; + meeting_gateway?: Maybe; meeting_hours?: Maybe; member_id?: Maybe; /** high / medium / low */ @@ -40892,6 +41218,7 @@ export type member_task_max_order_by = { executor_id?: InputMaybe; id?: InputMaybe; meet_id?: InputMaybe; + meeting_gateway?: InputMaybe; meeting_hours?: InputMaybe; member_id?: InputMaybe; /** high / medium / low */ @@ -40913,6 +41240,7 @@ export type member_task_min_fields = { executor_id?: Maybe; id?: Maybe; meet_id?: Maybe; + meeting_gateway?: Maybe; meeting_hours?: Maybe; member_id?: Maybe; /** high / medium / low */ @@ -40933,6 +41261,7 @@ export type member_task_min_order_by = { executor_id?: InputMaybe; id?: InputMaybe; meet_id?: InputMaybe; + meeting_gateway?: InputMaybe; meeting_hours?: InputMaybe; member_id?: InputMaybe; /** high / medium / low */ @@ -40974,6 +41303,7 @@ export type member_task_order_by = { id?: InputMaybe; meet?: InputMaybe; meet_id?: InputMaybe; + meeting_gateway?: InputMaybe; meeting_hours?: InputMaybe; member?: InputMaybe; member_id?: InputMaybe; @@ -41009,6 +41339,8 @@ export enum member_task_select_column { /** column name */ meet_id = 'meet_id', /** column name */ + meeting_gateway = 'meeting_gateway', + /** column name */ meeting_hours = 'meeting_hours', /** column name */ member_id = 'member_id', @@ -41045,6 +41377,7 @@ export type member_task_set_input = { has_meeting?: InputMaybe; id?: InputMaybe; meet_id?: InputMaybe; + meeting_gateway?: InputMaybe; meeting_hours?: InputMaybe; member_id?: InputMaybe; /** high / medium / low */ @@ -41107,6 +41440,7 @@ export type member_task_stream_cursor_value_input = { has_meeting?: InputMaybe; id?: InputMaybe; meet_id?: InputMaybe; + meeting_gateway?: InputMaybe; meeting_hours?: InputMaybe; member_id?: InputMaybe; /** high / medium / low */ @@ -41149,6 +41483,8 @@ export enum member_task_update_column { /** column name */ meet_id = 'meet_id', /** column name */ + meeting_gateway = 'meeting_gateway', + /** column name */ meeting_hours = 'meeting_hours', /** column name */ member_id = 'member_id', @@ -45426,6 +45762,10 @@ export type mutation_root = { delete_meet?: Maybe; /** delete single row from the table: "meet" */ delete_meet_by_pk?: Maybe; + /** delete data from the table: "meet_member" */ + delete_meet_member?: Maybe; + /** delete single row from the table: "meet_member" */ + delete_meet_member_by_pk?: Maybe; /** delete data from the table: "member" */ delete_member?: Maybe; /** delete data from the table: "member_achievement" */ @@ -45614,6 +45954,10 @@ export type mutation_root = { delete_payment_log_by_pk?: Maybe; /** delete data from the table: "permission" */ delete_permission?: Maybe; + /** delete data from the table: "permission_audit_log" */ + delete_permission_audit_log?: Maybe; + /** delete single row from the table: "permission_audit_log" */ + delete_permission_audit_log_by_pk?: Maybe; /** delete single row from the table: "permission" */ delete_permission_by_pk?: Maybe; /** delete data from the table: "permission_group" */ @@ -46386,6 +46730,10 @@ export type mutation_root = { insert_media_one?: Maybe; /** insert data into the table: "meet" */ insert_meet?: Maybe; + /** insert data into the table: "meet_member" */ + insert_meet_member?: Maybe; + /** insert a single row into the table: "meet_member" */ + insert_meet_member_one?: Maybe; /** insert a single row into the table: "meet" */ insert_meet_one?: Maybe; /** insert data into the table: "member" */ @@ -46582,6 +46930,10 @@ export type mutation_root = { insert_payment_log_one?: Maybe; /** insert data into the table: "permission" */ insert_permission?: Maybe; + /** insert data into the table: "permission_audit_log" */ + insert_permission_audit_log?: Maybe; + /** insert a single row into the table: "permission_audit_log" */ + insert_permission_audit_log_one?: Maybe; /** insert data into the table: "permission_group" */ insert_permission_group?: Maybe; /** insert a single row into the table: "permission_group" */ @@ -47530,6 +47882,12 @@ export type mutation_root = { update_meet_by_pk?: Maybe; /** update multiples rows of table: "meet" */ update_meet_many?: Maybe>>; + /** update data of the table: "meet_member" */ + update_meet_member?: Maybe; + /** update single row of the table: "meet_member" */ + update_meet_member_by_pk?: Maybe; + /** update multiples rows of table: "meet_member" */ + update_meet_member_many?: Maybe>>; /** update data of the table: "member" */ update_member?: Maybe; /** update data of the table: "member_achievement" */ @@ -47814,6 +48172,12 @@ export type mutation_root = { update_payment_log_many?: Maybe>>; /** update data of the table: "permission" */ update_permission?: Maybe; + /** update data of the table: "permission_audit_log" */ + update_permission_audit_log?: Maybe; + /** update single row of the table: "permission_audit_log" */ + update_permission_audit_log_by_pk?: Maybe; + /** update multiples rows of table: "permission_audit_log" */ + update_permission_audit_log_many?: Maybe>>; /** update single row of the table: "permission" */ update_permission_by_pk?: Maybe; /** update data of the table: "permission_group" */ @@ -49462,6 +49826,18 @@ export type mutation_rootdelete_meet_by_pkArgs = { }; +/** mutation root */ +export type mutation_rootdelete_meet_memberArgs = { + where: meet_member_bool_exp; +}; + + +/** mutation root */ +export type mutation_rootdelete_meet_member_by_pkArgs = { + id: Scalars['uuid']; +}; + + /** mutation root */ export type mutation_rootdelete_memberArgs = { where: member_bool_exp; @@ -50026,6 +50402,18 @@ export type mutation_rootdelete_permissionArgs = { }; +/** mutation root */ +export type mutation_rootdelete_permission_audit_logArgs = { + where: permission_audit_log_bool_exp; +}; + + +/** mutation root */ +export type mutation_rootdelete_permission_audit_log_by_pkArgs = { + id: Scalars['uuid']; +}; + + /** mutation root */ export type mutation_rootdelete_permission_by_pkArgs = { id: Scalars['String']; @@ -52499,6 +52887,20 @@ export type mutation_rootinsert_meetArgs = { }; +/** mutation root */ +export type mutation_rootinsert_meet_memberArgs = { + objects: Array; + on_conflict?: InputMaybe; +}; + + +/** mutation root */ +export type mutation_rootinsert_meet_member_oneArgs = { + object: meet_member_insert_input; + on_conflict?: InputMaybe; +}; + + /** mutation root */ export type mutation_rootinsert_meet_oneArgs = { object: meet_insert_input; @@ -53179,6 +53581,20 @@ export type mutation_rootinsert_permissionArgs = { }; +/** mutation root */ +export type mutation_rootinsert_permission_audit_logArgs = { + objects: Array; + on_conflict?: InputMaybe; +}; + + +/** mutation root */ +export type mutation_rootinsert_permission_audit_log_oneArgs = { + object: permission_audit_log_insert_input; + on_conflict?: InputMaybe; +}; + + /** mutation root */ export type mutation_rootinsert_permission_groupArgs = { objects: Array; @@ -56704,6 +57120,26 @@ export type mutation_rootupdate_meet_manyArgs = { }; +/** mutation root */ +export type mutation_rootupdate_meet_memberArgs = { + _set?: InputMaybe; + where: meet_member_bool_exp; +}; + + +/** mutation root */ +export type mutation_rootupdate_meet_member_by_pkArgs = { + _set?: InputMaybe; + pk_columns: meet_member_pk_columns_input; +}; + + +/** mutation root */ +export type mutation_rootupdate_meet_member_manyArgs = { + updates: Array; +}; + + /** mutation root */ export type mutation_rootupdate_memberArgs = { _append?: InputMaybe; @@ -57875,6 +58311,36 @@ export type mutation_rootupdate_permissionArgs = { }; +/** mutation root */ +export type mutation_rootupdate_permission_audit_logArgs = { + _append?: InputMaybe; + _delete_at_path?: InputMaybe; + _delete_elem?: InputMaybe; + _delete_key?: InputMaybe; + _prepend?: InputMaybe; + _set?: InputMaybe; + where: permission_audit_log_bool_exp; +}; + + +/** mutation root */ +export type mutation_rootupdate_permission_audit_log_by_pkArgs = { + _append?: InputMaybe; + _delete_at_path?: InputMaybe; + _delete_elem?: InputMaybe; + _delete_key?: InputMaybe; + _prepend?: InputMaybe; + _set?: InputMaybe; + pk_columns: permission_audit_log_pk_columns_input; +}; + + +/** mutation root */ +export type mutation_rootupdate_permission_audit_log_manyArgs = { + updates: Array; +}; + + /** mutation root */ export type mutation_rootupdate_permission_by_pkArgs = { _set?: InputMaybe; @@ -65237,6 +65703,7 @@ export type order_group_buying_log_stream_cursor_value_input = { /** columns and relationships of "order_log" */ export type order_log = { __typename?: 'order_log'; + app_id?: Maybe; auto_renewed_at?: Maybe; /** An object relationship */ coupon?: Maybe; @@ -65587,6 +66054,7 @@ export type order_log_bool_exp = { _and?: InputMaybe>; _not?: InputMaybe; _or?: InputMaybe>; + app_id?: InputMaybe; auto_renewed_at?: InputMaybe; coupon?: InputMaybe; created_at?: InputMaybe; @@ -66051,6 +66519,7 @@ export type order_log_inc_input = { /** input type for inserting data into table "order_log" */ export type order_log_insert_input = { + app_id?: InputMaybe; auto_renewed_at?: InputMaybe; coupon?: InputMaybe; created_at?: InputMaybe; @@ -66101,6 +66570,7 @@ export type order_log_insert_input = { /** aggregate max on columns */ export type order_log_max_fields = { __typename?: 'order_log_max_fields'; + app_id?: Maybe; auto_renewed_at?: Maybe; created_at?: Maybe; custom_id?: Maybe; @@ -66133,6 +66603,7 @@ export type order_log_max_fields = { /** order by max() on columns of table "order_log" */ export type order_log_max_order_by = { + app_id?: InputMaybe; auto_renewed_at?: InputMaybe; created_at?: InputMaybe; custom_id?: InputMaybe; @@ -66166,6 +66637,7 @@ export type order_log_max_order_by = { /** aggregate min on columns */ export type order_log_min_fields = { __typename?: 'order_log_min_fields'; + app_id?: Maybe; auto_renewed_at?: Maybe; created_at?: Maybe; custom_id?: Maybe; @@ -66198,6 +66670,7 @@ export type order_log_min_fields = { /** order by min() on columns of table "order_log" */ export type order_log_min_order_by = { + app_id?: InputMaybe; auto_renewed_at?: InputMaybe; created_at?: InputMaybe; custom_id?: InputMaybe; @@ -66253,6 +66726,7 @@ export type order_log_on_conflict = { /** Ordering options when selecting data from "order_log". */ export type order_log_order_by = { + app_id?: InputMaybe; auto_renewed_at?: InputMaybe; coupon?: InputMaybe; created_at?: InputMaybe; @@ -66307,6 +66781,8 @@ export type order_log_prepend_input = { /** select columns of table "order_log" */ export enum order_log_select_column { + /** column name */ + app_id = 'app_id', /** column name */ auto_renewed_at = 'auto_renewed_at', /** column name */ @@ -66373,6 +66849,7 @@ export enum order_log_select_column_order_log_aggregate_bool_exp_bool_or_argumen /** input type for updating data in table "order_log" */ export type order_log_set_input = { + app_id?: InputMaybe; auto_renewed_at?: InputMaybe; created_at?: InputMaybe; custom_id?: InputMaybe; @@ -66483,6 +66960,7 @@ export type order_log_stream_cursor_input = { /** Initial value of the column from where the streaming should start */ export type order_log_stream_cursor_value_input = { + app_id?: InputMaybe; auto_renewed_at?: InputMaybe; created_at?: InputMaybe; custom_id?: InputMaybe; @@ -66543,6 +67021,8 @@ export type order_log_sum_order_by = { /** update columns of table "order_log" */ export enum order_log_update_column { + /** column name */ + app_id = 'app_id', /** column name */ auto_renewed_at = 'auto_renewed_at', /** column name */ @@ -70234,6 +70714,248 @@ export type permission_aggregate_fieldscountArgs = { distinct?: InputMaybe; }; +/** columns and relationships of "permission_audit_log" */ +export type permission_audit_log = { + __typename?: 'permission_audit_log'; + app_id: Scalars['String']; + created_at: Scalars['timestamptz']; + id: Scalars['uuid']; + member_id: Scalars['String']; + new: Scalars['jsonb']; + old: Scalars['jsonb']; + target: Scalars['String']; +}; + + +/** columns and relationships of "permission_audit_log" */ +export type permission_audit_lognewArgs = { + path?: InputMaybe; +}; + + +/** columns and relationships of "permission_audit_log" */ +export type permission_audit_logoldArgs = { + path?: InputMaybe; +}; + +/** aggregated selection of "permission_audit_log" */ +export type permission_audit_log_aggregate = { + __typename?: 'permission_audit_log_aggregate'; + aggregate?: Maybe; + nodes: Array; +}; + +/** aggregate fields of "permission_audit_log" */ +export type permission_audit_log_aggregate_fields = { + __typename?: 'permission_audit_log_aggregate_fields'; + count: Scalars['Int']; + max?: Maybe; + min?: Maybe; +}; + + +/** aggregate fields of "permission_audit_log" */ +export type permission_audit_log_aggregate_fieldscountArgs = { + columns?: InputMaybe>; + distinct?: InputMaybe; +}; + +/** append existing jsonb value of filtered columns with new jsonb value */ +export type permission_audit_log_append_input = { + new?: InputMaybe; + old?: InputMaybe; +}; + +/** Boolean expression to filter rows from the table "permission_audit_log". All fields are combined with a logical 'AND'. */ +export type permission_audit_log_bool_exp = { + _and?: InputMaybe>; + _not?: InputMaybe; + _or?: InputMaybe>; + app_id?: InputMaybe; + created_at?: InputMaybe; + id?: InputMaybe; + member_id?: InputMaybe; + new?: InputMaybe; + old?: InputMaybe; + target?: InputMaybe; +}; + +/** unique or primary key constraints on table "permission_audit_log" */ +export enum permission_audit_log_constraint { + /** unique or primary key constraint on columns "id" */ + permission_audit_log_pkey = 'permission_audit_log_pkey' +} + +/** delete the field or element with specified path (for JSON arrays, negative integers count from the end) */ +export type permission_audit_log_delete_at_path_input = { + new?: InputMaybe>; + old?: InputMaybe>; +}; + +/** delete the array element with specified index (negative integers count from the end). throws an error if top level container is not an array */ +export type permission_audit_log_delete_elem_input = { + new?: InputMaybe; + old?: InputMaybe; +}; + +/** delete key/value pair or string element. key/value pairs are matched based on their key value */ +export type permission_audit_log_delete_key_input = { + new?: InputMaybe; + old?: InputMaybe; +}; + +/** input type for inserting data into table "permission_audit_log" */ +export type permission_audit_log_insert_input = { + app_id?: InputMaybe; + created_at?: InputMaybe; + id?: InputMaybe; + member_id?: InputMaybe; + new?: InputMaybe; + old?: InputMaybe; + target?: InputMaybe; +}; + +/** aggregate max on columns */ +export type permission_audit_log_max_fields = { + __typename?: 'permission_audit_log_max_fields'; + app_id?: Maybe; + created_at?: Maybe; + id?: Maybe; + member_id?: Maybe; + target?: Maybe; +}; + +/** aggregate min on columns */ +export type permission_audit_log_min_fields = { + __typename?: 'permission_audit_log_min_fields'; + app_id?: Maybe; + created_at?: Maybe; + id?: Maybe; + member_id?: Maybe; + target?: Maybe; +}; + +/** response of any mutation on the table "permission_audit_log" */ +export type permission_audit_log_mutation_response = { + __typename?: 'permission_audit_log_mutation_response'; + /** number of rows affected by the mutation */ + affected_rows: Scalars['Int']; + /** data from the rows affected by the mutation */ + returning: Array; +}; + +/** on_conflict condition type for table "permission_audit_log" */ +export type permission_audit_log_on_conflict = { + constraint: permission_audit_log_constraint; + update_columns?: Array; + where?: InputMaybe; +}; + +/** Ordering options when selecting data from "permission_audit_log". */ +export type permission_audit_log_order_by = { + app_id?: InputMaybe; + created_at?: InputMaybe; + id?: InputMaybe; + member_id?: InputMaybe; + new?: InputMaybe; + old?: InputMaybe; + target?: InputMaybe; +}; + +/** primary key columns input for table: permission_audit_log */ +export type permission_audit_log_pk_columns_input = { + id: Scalars['uuid']; +}; + +/** prepend existing jsonb value of filtered columns with new jsonb value */ +export type permission_audit_log_prepend_input = { + new?: InputMaybe; + old?: InputMaybe; +}; + +/** select columns of table "permission_audit_log" */ +export enum permission_audit_log_select_column { + /** column name */ + app_id = 'app_id', + /** column name */ + created_at = 'created_at', + /** column name */ + id = 'id', + /** column name */ + member_id = 'member_id', + /** column name */ + new = 'new', + /** column name */ + old = 'old', + /** column name */ + target = 'target' +} + +/** input type for updating data in table "permission_audit_log" */ +export type permission_audit_log_set_input = { + app_id?: InputMaybe; + created_at?: InputMaybe; + id?: InputMaybe; + member_id?: InputMaybe; + new?: InputMaybe; + old?: InputMaybe; + target?: InputMaybe; +}; + +/** Streaming cursor of the table "permission_audit_log" */ +export type permission_audit_log_stream_cursor_input = { + /** Stream column input with initial value */ + initial_value: permission_audit_log_stream_cursor_value_input; + /** cursor ordering */ + ordering?: InputMaybe; +}; + +/** Initial value of the column from where the streaming should start */ +export type permission_audit_log_stream_cursor_value_input = { + app_id?: InputMaybe; + created_at?: InputMaybe; + id?: InputMaybe; + member_id?: InputMaybe; + new?: InputMaybe; + old?: InputMaybe; + target?: InputMaybe; +}; + +/** update columns of table "permission_audit_log" */ +export enum permission_audit_log_update_column { + /** column name */ + app_id = 'app_id', + /** column name */ + created_at = 'created_at', + /** column name */ + id = 'id', + /** column name */ + member_id = 'member_id', + /** column name */ + new = 'new', + /** column name */ + old = 'old', + /** column name */ + target = 'target' +} + +export type permission_audit_log_updates = { + /** append existing jsonb value of filtered columns with new jsonb value */ + _append?: InputMaybe; + /** delete the field or element with specified path (for JSON arrays, negative integers count from the end) */ + _delete_at_path?: InputMaybe; + /** delete the array element with specified index (negative integers count from the end). throws an error if top level container is not an array */ + _delete_elem?: InputMaybe; + /** delete key/value pair or string element. key/value pairs are matched based on their key value */ + _delete_key?: InputMaybe; + /** prepend existing jsonb value of filtered columns with new jsonb value */ + _prepend?: InputMaybe; + /** sets the columns of the filtered rows to the given values */ + _set?: InputMaybe; + /** filter the rows which have to be updated */ + where: permission_audit_log_bool_exp; +}; + /** Boolean expression to filter rows from the table "permission". All fields are combined with a logical 'AND'. */ export type permission_bool_exp = { _and?: InputMaybe>; @@ -80845,12 +81567,10 @@ export type product_channel_bool_exp = { /** unique or primary key constraints on table "product_channel" */ export enum product_channel_constraint { - /** unique or primary key constraint on columns "channel_sku", "app_id" */ - product_channel_app_id_channel_sku_key = 'product_channel_app_id_channel_sku_key', /** unique or primary key constraint on columns "id" */ product_channel_pkey = 'product_channel_pkey', - /** unique or primary key constraint on columns "product_id", "channel_id" */ - product_channel_product_id_channel_id_key = 'product_channel_product_id_channel_id_key' + /** unique or primary key constraint on columns "channel_sku", "app_id", "product_id", "channel_id" */ + product_channel_product_id_channel_id_channel_sku_app_id_key = 'product_channel_product_id_channel_id_channel_sku_app_id_key' } /** input type for inserting data into table "product_channel" */ @@ -99954,6 +100674,12 @@ export type query_root = { meet_aggregate: meet_aggregate; /** fetch data from the table: "meet" using primary key columns */ meet_by_pk?: Maybe; + /** fetch data from the table: "meet_member" */ + meet_member: Array; + /** fetch aggregated fields from the table: "meet_member" */ + meet_member_aggregate: meet_member_aggregate; + /** fetch data from the table: "meet_member" using primary key columns */ + meet_member_by_pk?: Maybe; /** fetch data from the table: "member" */ member: Array; /** An array relationship */ @@ -100300,6 +101026,12 @@ export type query_root = { permission: Array; /** fetch aggregated fields from the table: "permission" */ permission_aggregate: permission_aggregate; + /** fetch data from the table: "permission_audit_log" */ + permission_audit_log: Array; + /** fetch aggregated fields from the table: "permission_audit_log" */ + permission_audit_log_aggregate: permission_audit_log_aggregate; + /** fetch data from the table: "permission_audit_log" using primary key columns */ + permission_audit_log_by_pk?: Maybe; /** fetch data from the table: "permission" using primary key columns */ permission_by_pk?: Maybe; /** fetch data from the table: "permission_group" */ @@ -103489,6 +104221,29 @@ export type query_rootmeet_by_pkArgs = { }; +export type query_rootmeet_memberArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type query_rootmeet_member_aggregateArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type query_rootmeet_member_by_pkArgs = { + id: Scalars['uuid']; +}; + + export type query_rootmemberArgs = { distinct_on?: InputMaybe>; limit?: InputMaybe; @@ -104866,6 +105621,29 @@ export type query_rootpermission_aggregateArgs = { }; +export type query_rootpermission_audit_logArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type query_rootpermission_audit_log_aggregateArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type query_rootpermission_audit_log_by_pkArgs = { + id: Scalars['uuid']; +}; + + export type query_rootpermission_by_pkArgs = { id: Scalars['String']; }; @@ -115411,6 +116189,14 @@ export type subscription_root = { meet_aggregate: meet_aggregate; /** fetch data from the table: "meet" using primary key columns */ meet_by_pk?: Maybe; + /** fetch data from the table: "meet_member" */ + meet_member: Array; + /** fetch aggregated fields from the table: "meet_member" */ + meet_member_aggregate: meet_member_aggregate; + /** fetch data from the table: "meet_member" using primary key columns */ + meet_member_by_pk?: Maybe; + /** fetch data from the table in a streaming manner: "meet_member" */ + meet_member_stream: Array; /** fetch data from the table in a streaming manner: "meet" */ meet_stream: Array; /** fetch data from the table: "member" */ @@ -115885,6 +116671,14 @@ export type subscription_root = { permission: Array; /** fetch aggregated fields from the table: "permission" */ permission_aggregate: permission_aggregate; + /** fetch data from the table: "permission_audit_log" */ + permission_audit_log: Array; + /** fetch aggregated fields from the table: "permission_audit_log" */ + permission_audit_log_aggregate: permission_audit_log_aggregate; + /** fetch data from the table: "permission_audit_log" using primary key columns */ + permission_audit_log_by_pk?: Maybe; + /** fetch data from the table in a streaming manner: "permission_audit_log" */ + permission_audit_log_stream: Array; /** fetch data from the table: "permission" using primary key columns */ permission_by_pk?: Maybe; /** fetch data from the table: "permission_group" */ @@ -120145,6 +120939,36 @@ export type subscription_rootmeet_by_pkArgs = { }; +export type subscription_rootmeet_memberArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type subscription_rootmeet_member_aggregateArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type subscription_rootmeet_member_by_pkArgs = { + id: Scalars['uuid']; +}; + + +export type subscription_rootmeet_member_streamArgs = { + batch_size: Scalars['Int']; + cursor: Array>; + where?: InputMaybe; +}; + + export type subscription_rootmeet_streamArgs = { batch_size: Scalars['Int']; cursor: Array>; @@ -121970,6 +122794,36 @@ export type subscription_rootpermission_aggregateArgs = { }; +export type subscription_rootpermission_audit_logArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type subscription_rootpermission_audit_log_aggregateArgs = { + distinct_on?: InputMaybe>; + limit?: InputMaybe; + offset?: InputMaybe; + order_by?: InputMaybe>; + where?: InputMaybe; +}; + + +export type subscription_rootpermission_audit_log_by_pkArgs = { + id: Scalars['uuid']; +}; + + +export type subscription_rootpermission_audit_log_streamArgs = { + batch_size: Scalars['Int']; + cursor: Array>; + where?: InputMaybe; +}; + + export type subscription_rootpermission_by_pkArgs = { id: Scalars['String']; }; @@ -140761,20 +141615,6 @@ export type GetActivityTicketsAggregateVariables = Exact<{ export type GetActivityTicketsAggregate = { __typename?: 'query_root', activity_ticket_aggregate: { __typename?: 'activity_ticket_aggregate', aggregate?: { __typename?: 'activity_ticket_aggregate_fields', sum?: { __typename?: 'activity_ticket_sum_fields', count?: number | null } | null } | null } }; -export type GET_APPOINTMENT_PERIOD_MEET_IDVariables = Exact<{ - orderProductId: Scalars['uuid']; -}>; - - -export type GET_APPOINTMENT_PERIOD_MEET_ID = { __typename?: 'query_root', order_product: Array<{ __typename?: 'order_product', id: any, options?: any | null }> }; - -export type GetAppointmentPlanPreviewVariables = Exact<{ - appointmentPlanId: Scalars['uuid']; -}>; - - -export type GetAppointmentPlanPreview = { __typename?: 'query_root', appointment_plan_by_pk?: { __typename?: 'appointment_plan', id: any, title: string, creator_id: string, meet_generation_method: string } | null }; - export type UpdateAppointmentPeriodVariables = Exact<{ orderProductId: Scalars['uuid']; startedAt: Scalars['timestamptz']; @@ -140792,13 +141632,6 @@ export type GetOrderProductVariables = Exact<{ export type GetOrderProduct = { __typename?: 'query_root', order_product_by_pk?: { __typename?: 'order_product', id: any, started_at?: any | null, ended_at?: any | null, deliverables?: any | null, options?: any | null } | null }; -export type GetCreatorInfoVariables = Exact<{ - creatorId?: InputMaybe; -}>; - - -export type GetCreatorInfo = { __typename?: 'query_root', member_public: Array<{ __typename?: 'member_public', id?: string | null, picture_url?: string | null, name?: string | null }> }; - export type GET_BUSINESS_SIGNUP_PROPERTY_ID_MAPVariables = Exact<{ condition: property_bool_exp; }>; @@ -141360,7 +142193,7 @@ export type GET_APPOINTMENT_PLAN_COLLECTIONVariables = Exact<{ }>; -export type GET_APPOINTMENT_PLAN_COLLECTION = { __typename?: 'query_root', appointment_plan: Array<{ __typename?: 'appointment_plan', id: any, title: string, description?: string | null, duration: any, price: any, support_locales?: any | null, is_private: boolean, reservation_amount: any, reservation_type?: string | null, capacity: number, reschedule_amount: number, reschedule_type?: string | null, currency: { __typename?: 'currency', id: string, label: string, unit: string, name: string }, appointment_enrollments: Array<{ __typename?: 'appointment_enrollment', member_id?: string | null, appointment_plan_id?: any | null, started_at?: any | null, canceled_at?: string | null }>, appointment_periods: Array<{ __typename?: 'appointment_period', started_at?: any | null, ended_at?: any | null, booked?: any | null, available?: boolean | null }> }> }; +export type GET_APPOINTMENT_PLAN_COLLECTION = { __typename?: 'query_root', appointment_plan: Array<{ __typename?: 'appointment_plan', id: any, title: string, description?: string | null, duration: any, price: any, support_locales?: any | null, is_private: boolean, reservation_amount: any, reservation_type?: string | null, capacity: number, reschedule_amount: number, reschedule_type?: string | null, default_meet_gateway: string, meet_generation_method: string, currency: { __typename?: 'currency', id: string, label: string, unit: string, name: string }, appointment_enrollments: Array<{ __typename?: 'appointment_enrollment', member_id?: string | null, appointment_plan_id?: any | null, started_at?: any | null, canceled_at?: string | null }>, appointment_periods: Array<{ __typename?: 'appointment_period', started_at?: any | null, ended_at?: any | null, booked?: any | null, available?: boolean | null }> }> }; export type GET_APPOINTMENT_PLANVariables = Exact<{ appointmentPlanId: Scalars['uuid']; @@ -141369,7 +142202,7 @@ export type GET_APPOINTMENT_PLANVariables = Exact<{ }>; -export type GET_APPOINTMENT_PLAN = { __typename?: 'query_root', appointment_plan_by_pk?: { __typename?: 'appointment_plan', id: any, title: string, description?: string | null, duration: any, price: any, capacity: number, reschedule_amount: number, reschedule_type?: string | null, support_locales?: any | null, currency: { __typename?: 'currency', id: string, label: string, unit: string, name: string }, appointment_enrollments: Array<{ __typename?: 'appointment_enrollment', member_id?: string | null, appointment_plan_id?: any | null, started_at?: any | null, canceled_at?: string | null }>, appointment_periods: Array<{ __typename?: 'appointment_period', started_at?: any | null, ended_at?: any | null, booked?: any | null }>, creator?: { __typename?: 'member_public', id?: string | null, abstract?: string | null, picture_url?: string | null, name?: string | null, username?: string | null } | null } | null }; +export type GET_APPOINTMENT_PLAN = { __typename?: 'query_root', appointment_plan_by_pk?: { __typename?: 'appointment_plan', id: any, title: string, description?: string | null, duration: any, price: any, capacity: number, reservation_amount: any, reservation_type?: string | null, reschedule_amount: number, reschedule_type?: string | null, support_locales?: any | null, default_meet_gateway: string, meet_generation_method: string, currency: { __typename?: 'currency', id: string, label: string, unit: string, name: string }, appointment_enrollments: Array<{ __typename?: 'appointment_enrollment', member_id?: string | null, appointment_plan_id?: any | null, started_at?: any | null, canceled_at?: string | null }>, appointment_periods: Array<{ __typename?: 'appointment_period', started_at?: any | null, ended_at?: any | null, booked?: any | null, available?: boolean | null }>, creator?: { __typename?: 'member_public', id?: string | null, abstract?: string | null, picture_url?: string | null, name?: string | null, username?: string | null } | null } | null }; export type GET_ENROLLED_APPOINTMENT_PLANVariables = Exact<{ memberId?: InputMaybe; @@ -141394,6 +142227,16 @@ export type CANCEL_APPOINTMENTVariables = Exact<{ export type CANCEL_APPOINTMENT = { __typename?: 'mutation_root', update_order_product?: { __typename?: 'order_product_mutation_response', affected_rows: number } | null }; +export type GetMeetByAppointmentPlanIdAndPeriodVariables = Exact<{ + target: Scalars['uuid']; + startedAt: Scalars['timestamptz']; + endedAt: Scalars['timestamptz']; + appId: Scalars['String']; +}>; + + +export type GetMeetByAppointmentPlanIdAndPeriod = { __typename?: 'query_root', meet: Array<{ __typename?: 'meet', id: any, host_member_id: string, meet_members: Array<{ __typename?: 'meet_member', id: any, member_id: string }> }> }; + export type GET_POST_PREVIEW_COLLECTIONVariables = Exact<{ authorId?: InputMaybe; }>; @@ -141823,6 +142666,34 @@ export type DELETE_ISSUE_REPLYVariables = Exact<{ export type DELETE_ISSUE_REPLY = { __typename?: 'mutation_root', delete_issue_reply_reaction?: { __typename?: 'issue_reply_reaction_mutation_response', affected_rows: number } | null, delete_issue_reply?: { __typename?: 'issue_reply_mutation_response', affected_rows: number } | null }; +export type UpdateMeetVariables = Exact<{ + meetId: Scalars['uuid']; + data?: InputMaybe; +}>; + + +export type UpdateMeet = { __typename?: 'mutation_root', update_meet_by_pk?: { __typename?: 'meet', id: any } | null }; + +export type GetMeetByTargetAndPeriodVariables = Exact<{ + appId: Scalars['String']; + target: Scalars['uuid']; + startedAt: Scalars['timestamptz']; + endedAt: Scalars['timestamptz']; + memberId: Scalars['String']; +}>; + + +export type GetMeetByTargetAndPeriod = { __typename?: 'query_root', meet: Array<{ __typename?: 'meet', id: any, options: any }> }; + +export type GetOverlapMeetsVariables = Exact<{ + appId: Scalars['String']; + startedAt: Scalars['timestamptz']; + endedAt: Scalars['timestamptz']; +}>; + + +export type GetOverlapMeets = { __typename?: 'query_root', meet: Array<{ __typename?: 'meet', id: any, host_member_id: string, target: any, service_id?: any | null }> }; + export type GET_MEMBERVariables = Exact<{ memberId: Scalars['String']; }>; @@ -142440,6 +143311,13 @@ export type GET_PRODUCT_EDITOR_IDSVariables = Exact<{ export type GET_PRODUCT_EDITOR_IDS = { __typename?: 'query_root', program: Array<{ __typename?: 'program', program_roles: Array<{ __typename?: 'program_role', id: any, member_id: string, name: string }> }>, podcast_program: Array<{ __typename?: 'podcast_program', podcast_program_roles: Array<{ __typename?: 'podcast_program_role', id: any, member_id: string, name: string }> }> }; +export type GetServiceVariables = Exact<{ + appId: Scalars['String']; +}>; + + +export type GetService = { __typename?: 'query_root', service: Array<{ __typename?: 'service', id: any, gateway: string }> }; + export type GET_ENROLLED_VOUCHER_COLLECTIONVariables = Exact<{ memberId: Scalars['String']; }>; @@ -142522,34 +143400,6 @@ export type GET_SYSTEMATIC_CATEGORY_PROGRAMSVariables = Exact<{ [key: string]: n export type GET_SYSTEMATIC_CATEGORY_PROGRAMS = { __typename?: 'query_root', systematicCategoryProgram: Array<{ __typename?: 'program', id: any, cover_url?: string | null, cover_mobile_url?: string | null, cover_thumbnail_url?: string | null, title: string, abstract?: string | null, support_locales?: any | null, published_at?: any | null, is_subscription: boolean, is_sold_out?: boolean | null, is_private: boolean, list_price?: any | null, sale_price?: any | null, sold_at?: any | null, program_roles: Array<{ __typename?: 'program_role', id: any, name: string, member_id: string }>, program_plans: Array<{ __typename?: 'program_plan', id: any, type: number, title: string, description?: string | null, gains?: any | null, list_price: any, sale_price?: any | null, sold_at?: any | null, discount_down_price: any, period_amount?: any | null, period_type?: string | null, started_at?: any | null, ended_at?: any | null, is_participants_visible: boolean, published_at?: any | null, currency: { __typename?: 'currency', id: string, label: string, unit: string, name: string }, program_plan_enrollments_aggregate: { __typename?: 'program_plan_enrollment_aggregate', aggregate?: { __typename?: 'program_plan_enrollment_aggregate_fields', count: number } | null } }>, program_enrollments_aggregate: { __typename?: 'program_enrollment_aggregate', aggregate?: { __typename?: 'program_enrollment_aggregate_fields', count: number } | null }, program_content_sections: Array<{ __typename?: 'program_content_section', program_contents: Array<{ __typename?: 'program_content', duration?: any | null }>, program_contents_aggregate: { __typename?: 'program_content_aggregate', aggregate?: { __typename?: 'program_content_aggregate_fields', sum?: { __typename?: 'program_content_sum_fields', duration?: any | null } | null } | null } }> }> }; -export type GetPropertiesAndCategoriesVariables = Exact<{ [key: string]: never; }>; - - -export type GetPropertiesAndCategories = { __typename?: 'query_root', property: Array<{ __typename?: 'property', id: any, name: string }>, category: Array<{ __typename?: 'category', id: string, name: string }> }; - -export type UpdateMemberCreatedVariables = Exact<{ - memberId: Scalars['String']; -}>; - - -export type UpdateMemberCreated = { __typename?: 'mutation_root', update_member_by_pk?: { __typename?: 'member', id: string, username: string } | null }; - -export type UpdateMemberPropertiesVariables = Exact<{ - memberPropertiesInput: Array | member_property_insert_input; -}>; - - -export type UpdateMemberProperties = { __typename?: 'mutation_root', insert_member_property?: { __typename?: 'member_property_mutation_response', affected_rows: number } | null }; - -export type InsertMemberTaskVariables = Exact<{ - currentMemberId: Scalars['String']; - managerId: Scalars['String']; - taskTitle: Scalars['String']; -}>; - - -export type InsertMemberTask = { __typename?: 'mutation_root', insert_member_task?: { __typename?: 'member_task_mutation_response', affected_rows: number } | null }; - export type GetMemberByUsernameVariables = Exact<{ appId: Scalars['String']; username: Scalars['String']; diff --git a/src/helpers/translation.ts b/src/helpers/translation.ts index f6cccd8c1..7d2162e5c 100644 --- a/src/helpers/translation.ts +++ b/src/helpers/translation.ts @@ -467,8 +467,8 @@ export const commonMessages = { publish: { id: 'common.text.publish', defaultMessage: 'publish' }, emailIsAlreadyExist: { id: 'common.text.emailIsAlreadyExist', defaultMessage: 'Email is already exist' }, usernameIsAlreadyExist: { id: 'common.text.usernameIsAlreadyExist', defaultMessage: 'Username is already exist' }, - emailFormatError:{ id: 'common.text.emailFormatError', defaultMessage: 'Email format error' }, - emailChecking:{ id: 'common.text.emailChecking', defaultMessage: 'Email checking ...' }, + emailFormatError: { id: 'common.text.emailFormatError', defaultMessage: 'Email format error' }, + emailChecking: { id: 'common.text.emailChecking', defaultMessage: 'Email checking ...' }, }), } @@ -800,11 +800,6 @@ export const productMessages = { }), }, appointment: { - status: defineMessages({ - booked: { id: 'product.appointment.status.booked', defaultMessage: '已預約' }, - closed: { id: 'product.appointment.status.closed', defaultMessage: '已關閉' }, - bookable: { id: 'product.appointment.status.bookable', defaultMessage: '可預約' }, - }), warningText: defineMessages({ news: { id: 'product.appointment.warning.text', diff --git a/src/hooks/appointment.ts b/src/hooks/appointment.ts index 56a6b2698..ab513fb51 100644 --- a/src/hooks/appointment.ts +++ b/src/hooks/appointment.ts @@ -1,4 +1,5 @@ import { gql, useMutation, useQuery } from '@apollo/client' +import { useApp } from 'lodestar-app-element/src/contexts/AppContext' import moment from 'moment' import hasura from '../hasura' import { AppointmentPeriod, AppointmentPlan, ReservationType } from '../types/appointment' @@ -23,6 +24,8 @@ export const useAppointmentPlanCollection = (memberId: string, startedAt: Date, capacity reschedule_amount reschedule_type + default_meet_gateway + meet_generation_method currency { id label @@ -61,6 +64,8 @@ export const useAppointmentPlanCollection = (memberId: string, startedAt: Date, phone: null, supportLocales: appointmentPlan.support_locales, capacity: appointmentPlan.capacity, + defaultMeetGateway: appointmentPlan.default_meet_gateway, + meetGenerationMethod: appointmentPlan.meet_generation_method, currency: { id: appointmentPlan.currency.id, label: appointmentPlan.currency.label, @@ -108,9 +113,13 @@ export const useAppointmentPlan = (appointmentPlanId: string, currentMemberId?: duration price capacity + reservation_amount + reservation_type reschedule_amount reschedule_type support_locales + default_meet_gateway + meet_generation_method currency { id label @@ -130,6 +139,7 @@ export const useAppointmentPlan = (appointmentPlanId: string, currentMemberId?: started_at ended_at booked + available } creator { id @@ -160,49 +170,53 @@ export const useAppointmentPlan = (appointmentPlanId: string, currentMemberId?: abstract: string | null } }) - | null = - loading || error || !data || !data.appointment_plan_by_pk - ? null - : { - id: data.appointment_plan_by_pk.id, - title: data.appointment_plan_by_pk.title, - description: data.appointment_plan_by_pk.description || '', - duration: data.appointment_plan_by_pk.duration, - price: data.appointment_plan_by_pk.price, - phone: null, - supportLocales: data.appointment_plan_by_pk.support_locales, - capacity: data.appointment_plan_by_pk.capacity, - rescheduleAmount: data.appointment_plan_by_pk?.reschedule_amount, - rescheduleType: (data.appointment_plan_by_pk.reschedule_type as ReservationType) || null, - currency: { - id: data.appointment_plan_by_pk.currency.id, - label: data.appointment_plan_by_pk.currency.label, - unit: data.appointment_plan_by_pk.currency.unit, - name: data.appointment_plan_by_pk.currency.name, - }, - periods: data.appointment_plan_by_pk.appointment_periods.map(period => ({ - id: `${period.started_at}`, - startedAt: new Date(period.started_at), - endedAt: new Date(period.ended_at), - booked: period.booked, - isBookedReachLimit: data.appointment_plan_by_pk?.capacity - ? data.appointment_plan_by_pk?.capacity !== -1 && period.booked >= data.appointment_plan_by_pk?.capacity - : false, - currentMemberBooked: data.appointment_plan_by_pk?.appointment_enrollments.some( - enrollment => - enrollment.member_id === currentMemberId && - enrollment.appointment_plan_id === data.appointment_plan_by_pk?.id && - enrollment.started_at === period.started_at && - !enrollment.canceled_at, - ), - })), - creator: { - id: data.appointment_plan_by_pk.creator?.id || '', - avatarUrl: data.appointment_plan_by_pk.creator?.picture_url || null, - name: data.appointment_plan_by_pk.creator?.name || data.appointment_plan_by_pk.creator?.username || '', - abstract: data.appointment_plan_by_pk.creator?.abstract || null, - }, - } + | null = data?.appointment_plan_by_pk + ? { + id: data.appointment_plan_by_pk.id, + title: data.appointment_plan_by_pk.title, + description: data.appointment_plan_by_pk.description || '', + duration: data.appointment_plan_by_pk.duration, + price: data.appointment_plan_by_pk.price, + phone: null, + supportLocales: data.appointment_plan_by_pk.support_locales, + capacity: data.appointment_plan_by_pk.capacity, + reservationAmount: data.appointment_plan_by_pk.reservation_amount, + reservationType: (data.appointment_plan_by_pk.reservation_type as ReservationType) || null, + rescheduleAmount: data.appointment_plan_by_pk?.reschedule_amount, + rescheduleType: (data.appointment_plan_by_pk.reschedule_type as ReservationType) || null, + defaultMeetGateway: data.appointment_plan_by_pk.default_meet_gateway, + meetGenerationMethod: data.appointment_plan_by_pk.meet_generation_method, + currency: { + id: data.appointment_plan_by_pk.currency.id, + label: data.appointment_plan_by_pk.currency.label, + unit: data.appointment_plan_by_pk.currency.unit, + name: data.appointment_plan_by_pk.currency.name, + }, + periods: data.appointment_plan_by_pk.appointment_periods.map(period => ({ + id: `${period.started_at}`, + startedAt: new Date(period.started_at), + endedAt: new Date(period.ended_at), + booked: period.booked, + available: !!period.available, + isBookedReachLimit: data.appointment_plan_by_pk?.capacity + ? data.appointment_plan_by_pk?.capacity !== -1 && period.booked >= data.appointment_plan_by_pk?.capacity + : false, + currentMemberBooked: data.appointment_plan_by_pk?.appointment_enrollments.some( + enrollment => + enrollment.member_id === currentMemberId && + enrollment.appointment_plan_id === data.appointment_plan_by_pk?.id && + enrollment.started_at === period.started_at && + !enrollment.canceled_at, + ), + })), + creator: { + id: data.appointment_plan_by_pk.creator?.id || '', + avatarUrl: data.appointment_plan_by_pk.creator?.picture_url || null, + name: data.appointment_plan_by_pk.creator?.name || data.appointment_plan_by_pk.creator?.username || '', + abstract: data.appointment_plan_by_pk.creator?.abstract || null, + }, + } + : null return { loadingAppointmentPlan: loading, @@ -289,3 +303,62 @@ export const useCancelAppointment = (orderProductId: string, options: any) => { }, }) } + +export const useMeetByAppointmentPlanIdAndPeriod = (appointmentPlanId: string, startedAt: Date, endedAt: Date) => { + const { id: appId } = useApp() + const { loading, data, error } = useQuery< + hasura.GetMeetByAppointmentPlanIdAndPeriod, + hasura.GetMeetByAppointmentPlanIdAndPeriodVariables + >( + gql` + query GetMeetByAppointmentPlanIdAndPeriod( + $target: uuid! + $startedAt: timestamptz! + $endedAt: timestamptz! + $appId: String! + ) { + meet( + where: { + target: { _eq: $target } + started_at: { _eq: $startedAt } + ended_at: { _eq: $endedAt } + app_id: { _eq: $appId } + deleted_at: { _is_null: true } + meet_members: { deleted_at: { _is_null: true } } + } + ) { + id + host_member_id + meet_members { + id + member_id + } + } + } + `, + { + variables: { + target: appointmentPlanId, + startedAt: startedAt.toISOString(), + endedAt: endedAt.toISOString(), + appId, + }, + }, + ) + const meet = data?.meet?.[0] + ? { + id: data.meet[0].id, + hostMemberId: data.meet[0].host_member_id, + meetMembers: data.meet[0].meet_members.map(v => ({ + id: v.id, + memberId: v.member_id, + })), + } + : null + + return { + loading, + meet, + error, + } +} diff --git a/src/hooks/meet.ts b/src/hooks/meet.ts new file mode 100644 index 000000000..305463e18 --- /dev/null +++ b/src/hooks/meet.ts @@ -0,0 +1,77 @@ +import { gql, useMutation, useQuery } from '@apollo/client' +import { useApp } from 'lodestar-app-element/src/contexts/AppContext' +import hasura from '../hasura' + +export const useMutateMeet = () => { + const [updateMeet] = useMutation(gql` + mutation UpdateMeet($meetId: uuid!, $data: jsonb) { + update_meet_by_pk(pk_columns: { id: $meetId }, _set: { options: $data }) { + id + } + } + `) + return { + updateMeet, + } +} + +export const useOverlapMeets = (startedAt: Date, endedAt: Date) => { + const { id: appId } = useApp() + const { loading, data } = useQuery(GetOverlapMeets, { + variables: { appId, startedAt: startedAt.toISOString(), endedAt: endedAt.toISOString() }, + }) + const overlapMeets: { + id: string + target: string + hostMemberId: string + serviceId: string + }[] = + data?.meet.map(v => ({ + id: v.id, + target: v.target, + hostMemberId: v.host_member_id, + serviceId: v.service_id, + })) || [] + return { loading, overlapMeets } +} + +export const GetMeetByTargetAndPeriod = gql` + query GetMeetByTargetAndPeriod( + $appId: String! + $target: uuid! + $startedAt: timestamptz! + $endedAt: timestamptz! + $memberId: String! + ) { + meet( + where: { + app_id: { _eq: $appId } + target: { _eq: $target } + started_at: { _eq: $startedAt } + ended_at: { _eq: $endedAt } + meet_members: { member_id: { _eq: $memberId } } + } + ) { + id + options + } + } +` + +export const GetOverlapMeets = gql` + query GetOverlapMeets($appId: String!, $startedAt: timestamptz!, $endedAt: timestamptz!) { + meet( + where: { + app_id: { _eq: $appId } + started_at: { _lte: $endedAt } + ended_at: { _gte: $startedAt } + deleted_at: { _is_null: true } + } + ) { + id + host_member_id + target + service_id + } + } +` diff --git a/src/hooks/service.ts b/src/hooks/service.ts new file mode 100644 index 000000000..5749d664b --- /dev/null +++ b/src/hooks/service.ts @@ -0,0 +1,28 @@ +import { gql, useQuery } from '@apollo/client' +import { useApp } from 'lodestar-app-element/src/contexts/AppContext' +import hasura from '../hasura' + +export const useService = () => { + const { id: appId } = useApp() + const { loading, data } = useQuery( + gql` + query GetService($appId: String!) { + service(where: { app_id: { _eq: $appId } }) { + id + gateway + } + } + `, + { variables: { appId } }, + ) + const services: { id: string; gateway: string }[] = + data?.service.map(v => ({ + id: v.id, + gateway: v.gateway, + })) || [] + + return { + loading, + services, + } +} diff --git a/src/pages/CreatorPage.tsx b/src/pages/CreatorPage.tsx index 2cf76d9c4..af64c2b6d 100644 --- a/src/pages/CreatorPage.tsx +++ b/src/pages/CreatorPage.tsx @@ -388,7 +388,7 @@ const CreatorTabs: React.VFC<{ content: (
- +
diff --git a/src/types/appointment.ts b/src/types/appointment.ts index 873bc59cb..ffbcdf315 100644 --- a/src/types/appointment.ts +++ b/src/types/appointment.ts @@ -16,6 +16,8 @@ export type AppointmentPlan = { rescheduleAmount: number rescheduleType: ReservationType | null capacity: number + defaultMeetGateway: string + meetGenerationMethod: string } export type AppointmentPeriod = {