Skip to content

Commit

Permalink
Merge branch 'preprod' into NGC-998
Browse files Browse the repository at this point in the history
  • Loading branch information
bjlaa authored Sep 3, 2024
2 parents 06ddc68 + 343335b commit d9aedee
Show file tree
Hide file tree
Showing 15 changed files with 199 additions and 58 deletions.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function NorthStarIframe() {
ref={iFrameRef}
id="iframe-metabase-northstar"
title="Statistiques Northstar Metabase"
src="https://metabase-ngc.osc-fr1.scalingo.io/public/dashboard/0f6974c5-1254-47b4-b6d9-6e6f22a6faf7"
src="https://metabase.nosgestesclimat.fr/public/dashboard/0f6974c5-1254-47b4-b6d9-6e6f22a6faf7"
width="100%"
height="1800px"
className="border-none"></iframe>
Expand Down
6 changes: 3 additions & 3 deletions src/app/(large-layout)/stats/_components/StatsContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export default function StatsContent() {
<MetabaseIframe
id="stats-quali"
titre="stats-quali"
src="https://metabase-ngc.osc-fr1.scalingo.io/public/dashboard/f36c5cc4-abb9-4ac6-98b5-13bed7318e7d#titled=false"
src="https://metabase.nosgestesclimat.fr/public/dashboard/f36c5cc4-abb9-4ac6-98b5-13bed7318e7d#titled=false"
height="800px"
/>{' '}
</div>
Expand All @@ -172,13 +172,13 @@ export default function StatsContent() {
<MetabaseIframe
id="stats-orga"
titre="stats mode orga"
src="https://metabase-ngc.osc-fr1.scalingo.io/public/dashboard/f64f2de4-fc94-431e-a6c0-01f9c0095267#titled=false"
src="https://metabase.nosgestesclimat.fr/public/dashboard/f64f2de4-fc94-431e-a6c0-01f9c0095267#titled=false"
/>
<h3 className="mt-4">Mode "Challenge tes amis"</h3>
<MetabaseIframe
id="stats-amis"
titre="stats-amis"
src="https://metabase-ngc.osc-fr1.scalingo.io/public/dashboard/8a32d8a6-3716-40a7-9ce0-f9991c54acf4#titled=false"
src="https://metabase.nosgestesclimat.fr/public/dashboard/8a32d8a6-3716-40a7-9ce0-f9991c54acf4#titled=false"
/>{' '}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ export default function LaconicRanking({ group }: Props) {
}

const particpantsOrdered = group.participants.sort((a, b) => {
if (!a.simulation.computedResults || !b.simulation.computedResults) {
const computedResultsA = a.simulation.computedResults
const computedResultsB = b.simulation.computedResults

if (!computedResultsA || !computedResultsB) {
return 0
}

return a.simulation.computedResults[defaultMetric].bilan <
b.simulation.computedResults[defaultMetric].bilan
return computedResultsA?.[defaultMetric]?.bilan <
computedResultsB?.[defaultMetric]?.bilan
? -1
: 1
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@ import { useGetGroupStats } from '@/hooks/groups/useGetGroupStats'
import { useIsGroupOwner } from '@/hooks/groups/useIsGroupOwner'
import { useUser } from '@/publicodes-state'
import { Group, Results } from '@/types/groups'
import { QueryObserverResult } from '@tanstack/react-query'
import Classement from './groupResults/Classement'
import InviteBlock from './groupResults/InviteBlock'
import OwnerAdminSection from './groupResults/OwnerAdminSection'
import ParticipantAdminSection from './groupResults/ParticipantAdminSection'
import PointsFortsFaibles from './groupResults/PointsFortsFaibles'

type Props = {
export default function GroupResults({
group,
refetchGroup,
}: {
group: Group
}
export default function GroupResults({ group }: Props) {
refetchGroup: () => Promise<QueryObserverResult<Group, Error>>
}) {
const { user } = useUser()

const { isGroupOwner } = useIsGroupOwner({ group })
Expand All @@ -30,7 +34,7 @@ export default function GroupResults({ group }: Props) {

return (
<>
<Classement group={group} />
<Classement group={group} refetchGroup={refetchGroup} />

<InviteBlock group={group} />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,22 @@ import { Group, Participant } from '@/types/groups'
import { useState } from 'react'

import Trans from '@/components/translation/Trans'
import { defaultMetric } from '@/constants/metric'
import Emoji from '@/design-system/utils/Emoji'

import { defaultMetric } from '@/constants/metric'
import { formatCarbonFootprint } from '@/helpers/formatters/formatCarbonFootprint'
import { getTopThreeAndRestMembers } from '@/helpers/groups/getTopThreeAndRestMembers'
import { useUser } from '@/publicodes-state'
import { QueryObserverResult } from '@tanstack/react-query'
import ClassementMember from './classement/ClassementMember'

export default function Classement({ group }: { group: Group }) {
export default function Classement({
group,
refetchGroup,
}: {
group: Group
refetchGroup: () => Promise<QueryObserverResult<Group, Error>>
}) {
const [isExpanded, setIsExpanded] = useState(false)

const {
Expand Down Expand Up @@ -55,12 +63,13 @@ export default function Classement({ group }: { group: Group }) {
}

const { formattedValue, unit } = formatCarbonFootprint(
participant?.simulation?.computedResults[defaultMetric].bilan ?? ''
participant?.simulation?.computedResults?.[defaultMetric]?.bilan ??
''
)

const quantity = participant?.simulation?.computedResults[
const quantity = participant?.simulation?.computedResults?.[
defaultMetric
].bilan ? (
]?.bilan ? (
<span className="m-none leading-[160%]">
<strong>{formattedValue}</strong>{' '}
<span className="text-sm font-light">{unit}</span>
Expand All @@ -77,29 +86,34 @@ export default function Classement({ group }: { group: Group }) {
quantity={quantity}
isTopThree
isCurrentMember={participant.userId === userId}
group={group}
userId={participant.userId}
numberOfParticipants={group.participants.length}
refetchGroup={refetchGroup}
/>
)
})}
</ul>

{restOfMembers.length > 0 && (
<ul className="px-4 py-4">
<ul className="px-3 py-4">
{restOfMembers.length > 0 &&
restOfMembers
.filter(
(member: Participant, index: number) =>
(participant: Participant, index: number) =>
isExpanded || index + topThreeMembers?.length < 5
)
.map((member: Participant, index: number) => {
.map((participant: Participant, index: number) => {
const rank = `${index + 1 + topThreeMembers?.length}.`

const { formattedValue, unit } = formatCarbonFootprint(
member?.simulation?.computedResults[defaultMetric].bilan ?? ''
participant?.simulation?.computedResults?.[defaultMetric]
?.bilan
)

const quantity = member?.simulation?.computedResults[
const quantity = participant?.simulation?.computedResults?.[
defaultMetric
].bilan ? (
]?.bilan ? (
<span className="leading-[160%]">
<strong>{formattedValue}</strong>{' '}
<span className="text-sm font-light">{unit}</span>
Expand All @@ -110,11 +124,14 @@ export default function Classement({ group }: { group: Group }) {

return (
<ClassementMember
key={member._id}
name={member.name}
key={participant._id}
name={participant.name}
rank={rank}
quantity={quantity}
isCurrentMember={member.userId === userId}
isCurrentMember={participant.userId === userId}
group={group}
userId={participant.userId}
refetchGroup={refetchGroup}
/>
)
})}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,133 @@
'use client'

import TrashIcon from '@/components/icons/TrashIcon'
import Trans from '@/components/translation/Trans'
import Badge from '@/design-system/layout/Badge'
import { JSX } from 'react'
import ConfirmationModal from '@/design-system/modals/ConfirmationModal'
import { useIsGroupOwner } from '@/hooks/groups/useIsGroupOwner'
import { useRemoveParticipant } from '@/hooks/groups/useRemoveParticipant'
import { useClientTranslation } from '@/hooks/useClientTranslation'
import { Group } from '@/types/groups'
import { captureException } from '@sentry/nextjs'
import { QueryObserverResult } from '@tanstack/react-query'
import { JSX, useState } from 'react'
import { toast } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css'
import { twMerge } from 'tailwind-merge'

export default function ClassementMember({
rank,
name,
quantity,
isTopThree,
isCurrentMember,
group,
name,
userId,
numberOfParticipants,
refetchGroup,
}: {
rank: JSX.Element | string
name: string
quantity: JSX.Element | string
isTopThree?: boolean
isCurrentMember?: boolean
group: Group
userId: string
numberOfParticipants?: number
refetchGroup: () => Promise<QueryObserverResult<Group, Error>>
}) {
const [isConfirmationModalOpen, setIsConfirmationModalOpen] = useState(false)

const { t } = useClientTranslation()

const { isGroupOwner } = useIsGroupOwner({ group })

const { mutateAsync: removePartipant } = useRemoveParticipant()

async function handleDelete() {
if (!group) return

try {
await removePartipant({
groupId: group?._id,
userId: userId || '',
})

await refetchGroup()

setIsConfirmationModalOpen(false)

toast.success(t('Participant supprimé avec succès'))
} catch (error) {
toast.error(t('Une erreur est survenue'), {
autoClose: false,
})
captureException(error)
}
}

return (
<li className="flex items-center justify-between">
<div className="mb-0 flex items-center text-sm md:text-base">
<span
className={`mr-2 ${
isTopThree ? 'text-lg md:text-2xl' : 'ml-1 text-base md:text-lg'
}`}>
{rank}
</span>

{name}

{isCurrentMember && (
<Badge className="ml-2 inline rounded-xl border-pink-100 bg-pink-200 text-xs font-bold text-secondary-700">
<Trans>Vous</Trans>
</Badge>
)}
<li className="flex items-center justify-between gap-2">
<div className="flex flex-1 items-center justify-between">
<div className="mb-0 flex items-center text-sm md:text-base">
<span
className={`mr-2 ${
isTopThree ? 'text-lg md:text-2xl' : 'ml-1 text-base md:text-lg'
}`}>
{rank}
</span>

{name}

{isCurrentMember && (
<Badge className="ml-2 inline rounded-xl border-pink-100 bg-pink-200 text-xs font-bold text-secondary-700">
<Trans>Vous</Trans>
</Badge>
)}
</div>

<div>{quantity}</div>
</div>

<div>{quantity}</div>
{isGroupOwner &&
(isCurrentMember ? (
// Add a gap to keep the layout consistent
<div
className={
numberOfParticipants === undefined || numberOfParticipants > 1
? 'w-6'
: ''
}
/>
) : (
<>
<button
onClick={() => setIsConfirmationModalOpen(true)}
className="inline-flex h-6 w-6 items-center justify-center !p-0 transition-colors"
aria-label={t('{{name}}, supprimer cette participation', {
name,
})}>
<TrashIcon
className={twMerge(
'w-4 fill-default',
isTopThree ? 'fill-white hover:fill-primary-200' : ''
)}
/>
</button>

{isConfirmationModalOpen && (
<ConfirmationModal
onConfirm={handleDelete}
closeModal={() => setIsConfirmationModalOpen(false)}>
<p className="text-sm md:text-base">
<Trans>
Supprimer ce participant ? Cette opération est définitive.
</Trans>
</p>
</ConfirmationModal>
)}
</>
))}
</li>
)
}
11 changes: 9 additions & 2 deletions src/app/(simulation)/(large-layout)/amis/resultats/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import GoBackLink from '@/design-system/inputs/GoBackLink'
import { useFetchGroup } from '@/hooks/groups/useFetchGroup'
import { useGroupIdInQueryParams } from '@/hooks/groups/useGroupIdInQueryParams'
import { useGroupPagesGuard } from '@/hooks/navigation/useGroupPagesGuard'
import { ToastContainer } from 'react-toastify'
import EditableGroupTitle from './_components/EditableGroupTitle'
import GroupResults from './_components/GroupResults'

Expand All @@ -16,7 +17,11 @@ export default function GroupResultsPage() {
})

const { groupIdInQueryParams } = useGroupIdInQueryParams()
const { data: group, isLoading } = useFetchGroup(groupIdInQueryParams)
const {
data: group,
isLoading,
refetch: refetchGroup,
} = useFetchGroup(groupIdInQueryParams)

// If we are still fetching the group (or we are redirecting the user), we display a loader
if (!isGuardInit || isGuardRedirecting || isLoading) {
Expand All @@ -34,7 +39,9 @@ export default function GroupResultsPage() {

<EditableGroupTitle group={group} />

<GroupResults group={group} />
<GroupResults group={group} refetchGroup={refetchGroup} />

<ToastContainer />
</div>
)
}
2 changes: 1 addition & 1 deletion src/design-system/modals/ConfirmationModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default function ConfirmationModal({
isOpen
onRequestClose={closeModal}
style={customStyles}
className="fixed left-1/2 top-1/2 w-[40rem] max-w-full -translate-x-1/2 -translate-y-1/2 rounded-xl bg-white p-8"
className="fixed left-1/2 top-1/2 w-[40rem] max-w-[90vw] -translate-x-1/2 -translate-y-1/2 rounded-xl bg-white p-8"
overlayClassName="fixed top-0 left-0 right-0 bottom-0 bg-black bg-opacity-50 z-[10000] overflow-hidden">
{children}

Expand Down
4 changes: 4 additions & 0 deletions src/helpers/actions/filterRelevantMissingVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const filteredDottedNames: DottedName[] = [
'futureco-data . transport . ferry . groupe',
'futureco-data . transport . ferry . consommation de services',
'futureco-data . transport . ferry . voiture',
// @ts-expect-error Remove after the new model version is deployed
'services sociétaux . devenir producteur photovoltaique',
// @ts-expect-error Remove after the new model version is deployed
'services sociétaux . bien placer argent',
]

export const filterRelevantMissingVariables = ({
Expand Down
Loading

0 comments on commit d9aedee

Please sign in to comment.