Skip to content

Commit

Permalink
Scoutgame telegram quest and claim page (#4961)
Browse files Browse the repository at this point in the history
* Scoutgametelegram

* Remove twa from main package

* Add validation of initData

* Update env

* Update secret name

* Revert not found deletion

* Update model

* Initial daily claim gallery

* Added next reward countdown

* Improved daily claim styling

* Added bonus claim card

* Claim daily reward action and schema

* Removed scout quest models

* Update import charmClient

* Fixed broken build issues

* Add one e2e test

* Fixed broken stuffs

* Fixed images

* Fixed tsconfig

* Bumped core

* Fixed broken tscofig

* Updated core

* Bumped core

* Added quests

* Updated how we handle the user and avatar

* Added claim quest point

* Bumped core

* Remove @root from scoutgametelegram

* resolved pr comments

* Update bg image

* Added tests for claim daily reward

* Added tests for get daily claims

* Added tests for complete quest

* Fixed broken type issues

* Fixed broken tests

* Fixed window is not defined error

* Bumped core

* Added support for daily claim events

* Fixed issue with claim date

* log error loading user

* Fixed broken tests

---------

Co-authored-by: Valentin L <[email protected]>
  • Loading branch information
Devorein and valentinludu authored Nov 8, 2024
1 parent c290c7e commit fd385ef
Show file tree
Hide file tree
Showing 46 changed files with 1,254 additions and 56 deletions.
1 change: 1 addition & 0 deletions apps/scoutgame/components/common/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export function Header() {
<AppBar
position='static'
sx={{
zIndex: 1,
height: 58,
backgroundColor: { xs: 'transparent', md: 'var(--mui-palette-AppBar-darkBg, var(--AppBar-background))' }
}}
Expand Down
22 changes: 1 addition & 21 deletions apps/scoutgame/components/login/LaunchDate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { Box, Stack, Typography } from '@mui/material';
import { tierDistributionMap } from '@packages/scoutgame/waitlist/scoring/constants';
import { timeUntilFuture } from '@packages/utils/dates';
import Image from 'next/image';
import { useEffect, useState } from 'react';

Expand Down Expand Up @@ -64,24 +65,3 @@ function getClosestFutureLaunchDate() {

return closestDate;
}

function timeUntilFuture(date?: number) {
if (!date) {
return null; // No future dates available
}

const now = new Date().getTime();
const timeDifference = date - now;

const days = Math.floor(timeDifference / (1000 * 60 * 60 * 24));
const hours = Math.floor((timeDifference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((timeDifference % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((timeDifference % (1000 * 60)) / 1000);

const timeString = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(
2,
'0'
)}`;

return { days, timeString };
}
1 change: 1 addition & 0 deletions apps/scoutgame/theme/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const purpleDisabled = 'rgba(160, 108, 213, 0.25)'; // purple dark
export const secondaryText = '#69DDFF'; // blue
export const blackText = '#191919'; // black
export const secondaryLightText = '#D8E1FF'; // light blue
export const secondaryDarkText = '#0580A4'; // dark blue
export const primaryTextColorDarkMode = '#D8E1FF';

export const secondaryTextColorDarkMode = '#999';
Expand Down
6 changes: 4 additions & 2 deletions apps/scoutgame/theme/theme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
purpleDisabled,
secondaryText,
secondaryLightText,
blackText
blackText,
secondaryDarkText
} from './colors';

const interFont = Inter({
Expand Down Expand Up @@ -60,7 +61,8 @@ const themeOptions: Parameters<typeof createTheme>[0] = {
},
secondary: {
main: secondaryText,
light: secondaryLightText
light: secondaryLightText,
dark: secondaryDarkText
},
inputBackground: {
main: inputBackgroundDarkMode
Expand Down
2 changes: 1 addition & 1 deletion apps/scoutgame/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["../../node_modules", ".next/", "public/sw.js", "sw.js"]
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { prisma } from '@charmverse/core/prisma-client';
import { currentSeason } from '@packages/scoutgame/dates';
import { sendPoints } from '@packages/scoutgame/points/sendPoints';
import { sendPointsForMiscEvent } from '@packages/scoutgame/points/builderEvents/sendPointsForMiscEvent';

async function deleteBuilderAndRedistributePoints({ builderPath }: { builderPath: string }) {
const builder = await prisma.scout.findUnique({
Expand Down Expand Up @@ -58,13 +58,13 @@ async function deleteBuilderAndRedistributePoints({ builderPath }: { builderPath
});
for (const [scoutId, tokensPurchased] of Object.entries(nftPurchaseEventsRecord)) {
const points = tokensPurchased * 20;
await sendPoints({
await sendPointsForMiscEvent({
tx,
builderId: scoutId,
points,
description: `You received a ${points} point gift from Scout Game`,
claimed: true,
earnedAs: 'scout'
earnedAs: 'scout',
});
await prisma.userSeasonStats.update({
where: {
Expand Down
4 changes: 2 additions & 2 deletions apps/scoutgamecron/src/scripts/issuePoints.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { log } from '@charmverse/core/log';
import { prisma } from '@charmverse/core/prisma-client';
import { currentSeason, getLastWeek } from '@packages/scoutgame/dates';
import { sendPoints } from '@packages/scoutgame/points/sendPoints';
import { sendPointsForMiscEvent } from '@packages/scoutgame/points/builderEvents/sendPointsForMiscEvent';
import { refreshPointStatsFromHistory } from '@packages/scoutgame/points/refreshPointStatsFromHistory';

const fids: number[] = [];
Expand Down Expand Up @@ -37,7 +37,7 @@ async function issuePoints({ points }: { points: number }) {

await prisma.$transaction(
async (tx) => {
await sendPoints({
await sendPointsForMiscEvent({
builderId: scout.id,
points,
claimed: true,
Expand Down
3 changes: 3 additions & 0 deletions apps/scoutgametelegram/app/friends/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function FriendsPage() {
return <div>FriendsPage</div>;
}
16 changes: 16 additions & 0 deletions apps/scoutgametelegram/app/quests/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { QuestsPage } from 'components/quests/QuestsPage';
import { getDailyClaims } from 'lib/claims/getDailyClaims';
import { getQuests } from 'lib/quests/getQuests';
import { getUserFromSession } from 'lib/session/getUserFromSession';

export default async function Quests() {
const user = await getUserFromSession();

if (!user) {
return null;
}

const dailyClaims = await getDailyClaims(user.id);
const quests = await getQuests(user.id);
return <QuestsPage dailyClaims={dailyClaims} quests={quests} />;
}
22 changes: 22 additions & 0 deletions apps/scoutgametelegram/components/quests/QuestsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Box } from '@mui/material';

import { InfoBackgroundImage } from 'components/layout/InfoBackgroundImage';
import type { DailyClaim } from 'lib/claims/getDailyClaims';
import type { QuestInfo } from 'lib/quests/getQuests';

import { DailyClaimGallery } from './components/DailyClaimGallery/DailyClaimGallery';
import { QuestsList } from './components/QuestsList/QuestsList';

export function QuestsPage({ dailyClaims, quests }: { dailyClaims: DailyClaim[]; quests: QuestInfo[] }) {
return (
<>
<InfoBackgroundImage />
<Box sx={{ px: 5 }}>
<DailyClaimGallery dailyClaims={dailyClaims} />
</Box>
<Box sx={{ px: 1 }}>
<QuestsList quests={quests} />
</Box>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
'use client';

import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import { Stack, Typography } from '@mui/material';
import { DateTime } from 'luxon';
import Image from 'next/image';
import { useAction } from 'next-safe-action/hooks';

import { claimDailyRewardAction } from 'lib/claims/claimDailyRewardAction';
import type { DailyClaim } from 'lib/claims/getDailyClaims';

import { DailyClaimGift } from './DailyClaimGift';

export function DailyClaimCard({ dailyClaim }: { dailyClaim: DailyClaim }) {
const { execute: claimDailyReward, isExecuting } = useAction(claimDailyRewardAction);
const currentWeekDay = DateTime.fromJSDate(new Date()).weekday;
const isPastDay = currentWeekDay > dailyClaim.day;
const isClaimToday = currentWeekDay === dailyClaim.day;
const isClaimed = dailyClaim.claimed;
const buttonLabel = isClaimToday && !isClaimed ? 'Claim' : dailyClaim.isBonus ? 'Bonus' : `Day ${dailyClaim.day}`;
const canClaim = isClaimToday && !isClaimed && !isExecuting;
const variant = isPastDay ? 'disabled' : isClaimToday ? 'secondary' : 'primary';

return (
<Stack
sx={{
backgroundColor: isClaimed
? 'background.light'
: isPastDay
? 'background.dark'
: isClaimToday
? 'secondary.main'
: 'primary.dark',
height: 90,
paddingBottom: 0.25,
borderRadius: 1,
alignItems: 'center',
position: 'relative',
cursor: canClaim ? 'pointer' : 'default'
}}
onClick={() => {
if (canClaim) {
claimDailyReward({ isBonus: dailyClaim.isBonus, dayOfWeek: currentWeekDay });
}
}}
>
<Stack flex={1} position='relative' alignItems='center' justifyContent='center' width='100%'>
{!isClaimed ? (
<Stack sx={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }}>
{dailyClaim.isBonus ? (
<Stack direction='row' gap={0.5} alignItems='flex-end'>
<DailyClaimGift variant={variant} size={44} />
<DailyClaimGift variant={variant} size={70} />
<DailyClaimGift variant={variant} size={44} />
</Stack>
) : (
<DailyClaimGift variant={variant} size={64} />
)}
</Stack>
) : (
<CheckCircleIcon
fontSize='small'
color='secondary'
sx={{
position: 'absolute',
top: 5,
right: 5
}}
/>
)}
<Stack direction='row' gap={0.5} alignItems='center' zIndex={1} top={7.5} position='relative'>
<Typography fontWeight={600}>{dailyClaim.isBonus ? '+3' : '+1'}</Typography>
<Image src='/images/scout-game-profile-icon.png' alt='Scout game icon' width={15} height={8.5} />
</Stack>
</Stack>
<Typography
variant='body2'
color={isClaimToday && !isClaimed ? 'secondary.dark' : 'text.primary'}
fontWeight={600}
>
{buttonLabel}
</Typography>
</Stack>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Grid2 as Grid, Stack, Typography } from '@mui/material';

import type { DailyClaim } from 'lib/claims/getDailyClaims';

import { DailyClaimCard } from './DailyClaimCard';
import { NextClaimCountdown } from './NextClaimCountdown';

export function DailyClaimGallery({ dailyClaims }: { dailyClaims: DailyClaim[] }) {
return (
<Stack justifyContent='center' alignItems='center' gap={1} my={2}>
<Typography variant='h4' color='secondary' fontWeight={600} zIndex={1}>
Daily Claim
</Typography>
<NextClaimCountdown />
<Grid container spacing={1} width='100%'>
{dailyClaims.map((dailyClaim) => (
<Grid size={dailyClaim.isBonus ? 8 : 4} key={dailyClaim.day}>
<DailyClaimCard dailyClaim={dailyClaim} />
</Grid>
))}
</Grid>
</Stack>
);
}
Loading

0 comments on commit fd385ef

Please sign in to comment.