Skip to content

Commit

Permalink
🌐 Improve i18n collaboration type and timeSince parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Dec 29, 2023
1 parent 5124373 commit f26eafd
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 66 deletions.
46 changes: 46 additions & 0 deletions apps/builder/src/components/TimeSince.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { T } from '@tolgee/react'

type Props = {
date: string
}

export const TimeSince = ({ date }: Props) => {
const seconds = Math.floor(
(new Date().getTime() - new Date(date).getTime()) / 1000
)

let interval = seconds / 31536000

if (interval > 1) {
return (
<T keyName="timeSince.years" params={{ count: Math.floor(interval) }} />
)
}
interval = seconds / 2592000
if (interval > 1) {
return (
<T keyName="timeSince.months" params={{ count: Math.floor(interval) }} />
)
}
interval = seconds / 86400
if (interval > 1) {
return (
<T keyName="timeSince.days" params={{ count: Math.floor(interval) }} />
)
}
interval = seconds / 3600
if (interval > 1) {
return (
<T keyName="timeSince.hours" params={{ count: Math.floor(interval) }} />
)
}
interval = seconds / 60
if (interval > 1) {
return (
<T keyName="timeSince.minutes" params={{ count: Math.floor(interval) }} />
)
}
return (
<T keyName="timeSince.seconds" params={{ count: Math.floor(interval) }} />
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import { byId, isDefined } from '@typebot.io/lib'
import { CreateTokenModal } from './CreateTokenModal'
import { useApiTokens } from '../hooks/useApiTokens'
import { ApiTokenFromServer } from '../types'
import { parseTimeSince } from '@/helpers/parseTimeSince'
import { deleteApiTokenQuery } from '../queries/deleteApiTokenQuery'
import { T, useTranslate } from '@tolgee/react'
import { TimeSince } from '@/components/TimeSince'

type Props = { user: User }

Expand Down Expand Up @@ -84,7 +84,9 @@ export const ApiTokensList = ({ user }: Props) => {
{apiTokens?.map((token) => (
<Tr key={token.id}>
<Td>{token.name}</Td>
<Td>{parseTimeSince(t, token.createdAt)}</Td>
<Td>
<TimeSince date={token.createdAt} />
</Td>
<Td>
<Button
size="xs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import { deleteInvitationQuery } from '../queries/deleteInvitationQuery'
import { updateCollaboratorQuery } from '../queries/updateCollaboratorQuery'
import { deleteCollaboratorQuery } from '../queries/deleteCollaboratorQuery'
import { sendInvitationQuery } from '../queries/sendInvitationQuery'
import { TFnType, useTranslate } from '@tolgee/react'
import { useTranslate } from '@tolgee/react'
import { ReadableCollaborationType } from './ReadableCollaborationType'

export const CollaborationList = () => {
const { currentRole, workspace } = useWorkspace()
Expand Down Expand Up @@ -180,10 +181,7 @@ export const CollaborationList = () => {
</Text>
</HStack>
<Tag flexShrink={0}>
{convertCollaborationTypeEnumToReadable(
t,
CollaborationType.FULL_ACCESS
)}
<ReadableCollaborationType type={CollaborationType.FULL_ACCESS} />
</Tag>
</Flex>
)}
Expand Down Expand Up @@ -232,43 +230,25 @@ const CollaborationTypeMenuButton = ({
}: {
type: CollaborationType
onChange: (type: CollaborationType) => void
}) => {
const { t } = useTranslate()

return (
<Menu placement="bottom-end">
<MenuButton
flexShrink={0}
size="sm"
as={Button}
rightIcon={<ChevronLeftIcon transform={'rotate(-90deg)'} />}
>
{convertCollaborationTypeEnumToReadable(t, type)}
</MenuButton>
<MenuList minW={0}>
<Stack maxH={'35vh'} overflowY="scroll" spacing="0">
<MenuItem onClick={() => onChange(CollaborationType.READ)}>
{convertCollaborationTypeEnumToReadable(t, CollaborationType.READ)}
</MenuItem>
<MenuItem onClick={() => onChange(CollaborationType.WRITE)}>
{convertCollaborationTypeEnumToReadable(t, CollaborationType.WRITE)}
</MenuItem>
</Stack>
</MenuList>
</Menu>
)
}

export const convertCollaborationTypeEnumToReadable = (
t: TFnType,
type: CollaborationType
) => {
switch (type) {
case CollaborationType.READ:
return t('collaboration.roles.view.label')
case CollaborationType.WRITE:
return t('collaboration.roles.edit.label')
case CollaborationType.FULL_ACCESS:
return t('collaboration.roles.full.label')
}
}
}) => (
<Menu placement="bottom-end">
<MenuButton
flexShrink={0}
size="sm"
as={Button}
rightIcon={<ChevronLeftIcon transform={'rotate(-90deg)'} />}
>
<ReadableCollaborationType type={type} />
</MenuButton>
<MenuList minW={0}>
<Stack maxH={'35vh'} overflowY="scroll" spacing="0">
<MenuItem onClick={() => onChange(CollaborationType.READ)}>
<ReadableCollaborationType type={CollaborationType.READ} />
</MenuItem>
<MenuItem onClick={() => onChange(CollaborationType.WRITE)}>
<ReadableCollaborationType type={CollaborationType.WRITE} />
</MenuItem>
</Stack>
</MenuList>
</Menu>
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
} from '@chakra-ui/react'
import { CollaborationType } from '@typebot.io/prisma'
import React from 'react'
import { convertCollaborationTypeEnumToReadable } from './CollaborationList'
import { useTranslate } from '@tolgee/react'
import { ReadableCollaborationType } from './ReadableCollaborationType'

type Props = {
image?: string
Expand Down Expand Up @@ -50,16 +50,16 @@ export const CollaboratorItem = ({
name={name}
image={image}
isGuest={isGuest}
tag={convertCollaborationTypeEnumToReadable(t, type)}
type={type}
/>
</MenuButton>
{isOwner && (
<MenuList shadow="lg">
<MenuItem onClick={handleEditClick}>
{convertCollaborationTypeEnumToReadable(t, CollaborationType.WRITE)}
<ReadableCollaborationType type={CollaborationType.WRITE} />
</MenuItem>
<MenuItem onClick={handleViewClick}>
{convertCollaborationTypeEnumToReadable(t, CollaborationType.READ)}
<ReadableCollaborationType type={CollaborationType.READ} />
</MenuItem>
<MenuItem color="red.500" onClick={onDeleteClick}>
{t('remove')}
Expand All @@ -72,13 +72,13 @@ export const CollaboratorItem = ({

export const CollaboratorIdentityContent = ({
name,
tag,
type,
isGuest = false,
image,
email,
}: {
name?: string
tag?: string
type: CollaborationType
image?: string
isGuest?: boolean
email: string
Expand Down Expand Up @@ -106,7 +106,9 @@ export const CollaboratorIdentityContent = ({
</HStack>
<HStack flexShrink={0}>
{isGuest && <Tag color="gray.400">{t('pending')}</Tag>}
<Tag>{tag}</Tag>
<Tag>
<ReadableCollaborationType type={type} />
</Tag>
</HStack>
</HStack>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { T } from '@tolgee/react'
import { CollaborationType } from '@typebot.io/prisma'

type Props = { type: CollaborationType }
export const ReadableCollaborationType = ({ type }: Props) => {
switch (type) {
case CollaborationType.READ:
return <T keyName="collaboration.roles.view.label" />
case CollaborationType.WRITE:
return <T keyName="collaboration.roles.edit.label" />
case CollaborationType.FULL_ACCESS:
return <T keyName="collaboration.roles.full.label" />
}
}
19 changes: 11 additions & 8 deletions apps/builder/src/features/publish/components/PublishButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import { useRouter } from 'next/router'
import { isNotDefined } from '@typebot.io/lib'
import { ChangePlanModal } from '@/features/billing/components/ChangePlanModal'
import { isFreePlan } from '@/features/billing/helpers/isFreePlan'
import { parseTimeSince } from '@/helpers/parseTimeSince'
import { T, useTranslate } from '@tolgee/react'
import { trpc } from '@/lib/trpc'
import { useToast } from '@/hooks/useToast'
Expand All @@ -33,6 +32,7 @@ import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/const
import { ConfirmModal } from '@/components/ConfirmModal'
import { TextLink } from '@/components/TextLink'
import { useUser } from '@/features/account/hooks/useUser'
import { useTimeSince } from '@/hooks/useTimeSince'

type Props = ButtonProps & {
isMoreMenuDisabled?: boolean
Expand Down Expand Up @@ -61,6 +61,9 @@ export const PublishButton = ({
save,
publishedTypebotVersion,
} = useTypebot()
const timeSinceLastPublish = useTimeSince(
publishedTypebot?.updatedAt.toString()
)
const { showToast } = useToast()

const {
Expand Down Expand Up @@ -181,14 +184,14 @@ export const PublishButton = ({
label={
<Stack>
<Text>{t('publishButton.tooltip.nonPublishedChanges.label')}</Text>
{publishedTypebot ? (
{timeSinceLastPublish ? (
<Text fontStyle="italic">
{t('publishButton.tooltip.publishedVersion.from.label', {
timeSince: parseTimeSince(
t,
publishedTypebot.updatedAt.toString()
),
})}
<T
keyName="publishButton.tooltip.publishedVersion.from.label"
params={{
timeSince: timeSinceLastPublish,
}}
/>
</Text>
) : null}
</Stack>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { TFnType } from '@tolgee/react'
import { useTranslate } from '@tolgee/react'

export const useTimeSince = (date?: string) => {
const { t } = useTranslate()

if (!date) return

export const parseTimeSince = (t: TFnType, date: string) => {
const seconds = Math.floor(
(new Date().getTime() - new Date(date).getTime()) / 1000
)
Expand Down
3 changes: 1 addition & 2 deletions apps/builder/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@
"publishButton.published.label": "Published",
"publishButton.tooltip.nonPublishedChanges.label": "There are non published changes.",
"publishButton.tooltip.publishedVersion.ago.label": "ago",
"publishButton.tooltip.publishedVersion.from.label": "Published version from {timeSince}.",
"publishButton.tooltip.publishedVersion.from.label": "Published version from <timeSince>test</timeSince>.",
"remove": "Remove",
"share.button.label": "Share",
"share.button.popover.ariaLabel": "Open share popover",
Expand Down Expand Up @@ -310,7 +310,6 @@
"templates.modal.product.userOnboarding.description": "A bot that asks for new user information before he start using your product.",
"templates.modal.product.userOnboarding.name": "User Onboarding",
"templates.modal.useTemplateButton.label": "Use this template",
"templates.modal.useTemplateButton.labelt": "Use this templatet",
"timeSince.days": "{count}d ago",
"timeSince.hours": "{count}h ago",
"timeSince.minutes": "{count}m ago",
Expand Down

1 comment on commit f26eafd

@vercel
Copy link

@vercel vercel bot commented on f26eafd Dec 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

builder-v2-typebot-io.vercel.app
app.typebot.io
builder-v2-git-main-typebot-io.vercel.app

Please sign in to comment.