Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Production Release #1379

Merged
merged 21 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
name: Playwright Tests
on:
push:
- pull_request
- workflow_dispatch
permissions:
checks: write
pull-requests: write
contents: write
jobs:
test:
timeout-minutes: 10
Expand All @@ -22,3 +27,7 @@ jobs:
name: playwright-report
path: playwright-report/
retention-days: 30
- uses: daun/playwright-report-summary@v3
if: always()
with:
report-file: test-results.json
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ next-env.d.ts
/playwright-report/
/blob-report/
/playwright/.cache/
test-results.json
12 changes: 6 additions & 6 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,18 @@ const nextConfig = {
port: '',
pathname: '/uploads/**',
},
{
protocol: 'https',
hostname: 'storage.googleapis.com',
port: '',
pathname: '/jumper-static-assets/upload/**',
},
// {
// protocol: 'https',
// hostname: 'cdn.mygateway.xyz',
// port: '',
// pathname: '/**',
// },
{
protocol: 'https',
hostname: 'jumper-static.s3.us-east-2.amazonaws.com',
port: '',
pathname: '/**',
},
{
protocol: 'https',
hostname: 'resolve.mercle.xyz',
Expand Down
2 changes: 1 addition & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default defineConfig({
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
reporter: [['html'], ['json', { outputFile: 'test-results.json' }]],
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
Expand Down
4 changes: 2 additions & 2 deletions src/app/[lng]/(infos)/learn/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export async function generateMetadata({
title: `Jumper Learn | ${sliceStrToXChar(articleData.Title, 45)}`,
description: `${sliceStrToXChar(articleData.Subtitle, 60)}`,
siteName: siteName,
url: `${process.env.NEXT_PUBLIC_SITE_URL}/learn/${params.slug}/`,
url: `${process.env.NEXT_PUBLIC_SITE_URL}/learn/${params.slug}`,
images: [
{
url: `${article.url}${articleData.Image.data.attributes?.url}`,
Expand All @@ -44,7 +44,7 @@ export async function generateMetadata({
title: `Jumper Learn | ${sliceStrToXChar(articleData.Title, 45)}`,
description: articleData.Subtitle,
alternates: {
canonical: `${process.env.NEXT_PUBLIC_SITE_URL}/${params.slug}/`,
canonical: `${process.env.NEXT_PUBLIC_SITE_URL}/learn/${params.slug}`,
},
twitter: openGraph,
openGraph,
Expand Down
2 changes: 1 addition & 1 deletion src/app/[lng]/(infos)/learn/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export async function generateMetadata(): Promise<Metadata> {
title: 'Jumper Learn',
description: 'Jumper Learn is the blog of Jumper Exchange.',
alternates: {
canonical: `${process.env.NEXT_PUBLIC_SITE_URL}/learn/`,
canonical: `${process.env.NEXT_PUBLIC_SITE_URL}/learn`,
},
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/[lng]/(infos)/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export async function generateMetadata(): Promise<Metadata> {
title: 'Jumper Profile',
description: 'Jumper Profile is the profile page of Jumper Exchange.',
alternates: {
canonical: `${process.env.NEXT_PUBLIC_SITE_URL}/profile/`,
canonical: `${process.env.NEXT_PUBLIC_SITE_URL}/profile`,
},
};
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/[lng]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ export function generateMetadata({ params }: RootLayoutProps): Metadata {
title,
description,
alternates: {
canonical: `${process.env.NEXT_PUBLIC_SITE_URL}/${params.lng === 'en' ? '' : params.lng}`,
canonical: `${process.env.NEXT_PUBLIC_SITE_URL}`,
},
openGraph: {
title: title,
description,
siteName,
url: `${process.env.NEXT_PUBLIC_SITE_URL}/${params.lng === 'en' ? '' : params.lng}`,
url: `${process.env.NEXT_PUBLIC_SITE_URL}`,
images: [
{
url: 'https://jumper.exchange/preview.png', // Default image
Expand Down
2 changes: 1 addition & 1 deletion src/app/[lng]/superfest/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export async function generateMetadata(): Promise<Metadata> {
title: 'Jumper | Superfest',
description: 'Dive into the Superchain DeFi Festival!',
alternates: {
canonical: `${process.env.NEXT_PUBLIC_SITE_URL}/superfest/`,
canonical: `${process.env.NEXT_PUBLIC_SITE_URL}/superfest`,
},
};
}
Expand Down
69 changes: 21 additions & 48 deletions src/app/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,62 +9,35 @@ function withoutTrailingSlash(url: string) {
return url.endsWith('/') ? url.slice(0, -1) : url;
}

function generateAlternates(path: string) {
return {
languages: {
...locales.reduce((acc, loc) => {
const pages = {
...acc,
[loc]: withoutTrailingSlash(
`${process.env.NEXT_PUBLIC_SITE_URL}${loc !== 'en' ? `/${loc}` : ''}${path}`,
),
};

return pages;
}, {}),
},
};
}

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
// paths
const routes = pages.flatMap((route: SitemapPage) => {
return locales.map((locale) => {
return {
url: withoutTrailingSlash(
`${process.env.NEXT_PUBLIC_SITE_URL}${locale !== 'en' ? `/${locale}` : ''}${route.path}`,
),
lastModified: new Date().toISOString().split('T')[0],
changeFrequency: 'weekly' as ChangeFrequency,
alternates: generateAlternates(route.path),
priority: route.priority,
};
});
return {
url: withoutTrailingSlash(
`${process.env.NEXT_PUBLIC_SITE_URL}${route.path}`,
),
lastModified: new Date().toISOString().split('T')[0],
changeFrequency: 'weekly' as ChangeFrequency,
priority: route.priority,
};
});

// articles by slug
const articles = await getArticles().then(
(article: StrapiResponse<BlogArticleData>) => {
return locales.flatMap((locale) => {
return article.data.map((el) => {
return {
url: withoutTrailingSlash(
`${process.env.NEXT_PUBLIC_SITE_URL}${locale !== 'en' ? `/${locale}` : ''}${JUMPER_LEARN_PATH}${el.attributes.Slug}`,
),
lastModified: new Date(
el.attributes.updatedAt ||
el.attributes.publishedAt ||
Date.now(),
)
.toISOString()
.split('T')[0],
changeFrequency: 'weekly' as ChangeFrequency,
alternates: generateAlternates(
`${JUMPER_LEARN_PATH}${el.attributes.Slug}`,
),
priority: 0.8,
};
});
return article.data.map((el) => {
return {
url: withoutTrailingSlash(
`${process.env.NEXT_PUBLIC_SITE_URL}${JUMPER_LEARN_PATH}${el.attributes.Slug}`,
),
lastModified: new Date(
el.attributes.updatedAt || el.attributes.publishedAt || Date.now(),
)
.toISOString()
.split('T')[0],
changeFrequency: 'weekly' as ChangeFrequency,
priority: 0.8,
};
});
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ import {
InstructionsAccordionLinkBox,
InstructionsAccordionToggle,
} from '.';
import { useUserTracking } from 'src/hooks/userTracking';
import {
TrackingAction,
TrackingCategory,
TrackingEventParameter,
} from 'src/const/trackingKeys';

interface InstructionsAccordionItemProps extends InstructionItemProps {
index: number;
Expand Down Expand Up @@ -53,6 +59,7 @@ export const InstructionsAccordionItem = ({
}: InstructionsAccordionItemProps) => {
const [open, setOpen] = useState(false);
const theme = useTheme();
const { trackEvent } = useUserTracking();
const isTablet = useMediaQuery(theme.breakpoints.up('sm' as Breakpoint));
const handleOpen:
| MouseEventHandler<HTMLDivElement | HTMLButtonElement>
Expand All @@ -69,6 +76,20 @@ export const InstructionsAccordionItem = ({
}
}, []);

const handleClick = (i: number) => {
trackEvent({
category: TrackingCategory.Quests,
action: TrackingAction.ClickMissionCtaSteps,
label: `click-mission-cta-steps`,
data: {
[TrackingEventParameter.MissionCtaStepsTitle]: title || '',
[TrackingEventParameter.MissionCtaStepsLink]: buttonLinks?.[i] || '',
[TrackingEventParameter.MissionCtaStepsCTA]: buttonTitles?.[i] || '',
[TrackingEventParameter.MissionCtaStepsIndex]: index || -1,
},
});
};

return (
<InstructionsAccordionItemContainer
sx={{
Expand Down Expand Up @@ -140,6 +161,7 @@ export const InstructionsAccordionItem = ({
target="_blank"
rel="noreferrer"
style={{ textDecoration: 'none', color: 'inherit' }}
onClick={() => handleClick(i)}
>
<InstructionsAccordionLinkBox>
<Typography
Expand Down
10 changes: 0 additions & 10 deletions src/components/Link.style.ts

This file was deleted.

31 changes: 31 additions & 0 deletions src/components/OptionalLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Link as MuiLink, type CSSObject } from '@mui/material';
import Link from 'next/link';
import type { PropsWithChildren } from 'react';

interface OptionalLinkProps {
href?: string;
ariaLabel?: string;
sx?: CSSObject;
}

export const OptionalLink: React.FC<PropsWithChildren<OptionalLinkProps>> = (
props,
) => {
if (props.href) {
return (
<MuiLink
component={Link}
href={props.href}
aria-label={props.ariaLabel}
style={{
textDecoration: 'inherit',
...(props.sx as React.CSSProperties),
}}
>
{props.children}
</MuiLink>
);
} else {
return props.children;
}
};
27 changes: 15 additions & 12 deletions src/components/ProfilePage/AddressBox/AddressBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import OpenInNewIcon from '@mui/icons-material/OpenInNew';
import { useTheme } from '@mui/material';
import Image from 'next/image';
import { useTranslation } from 'react-i18next';
import { useMercleNft } from 'src/hooks/useMercleNft';
import type { Address } from 'viem';
import { useEnsName } from 'wagmi';
import { mainnet } from 'wagmi/chains';
Expand All @@ -18,12 +19,12 @@ import {
interface AddressBoxProps {
address?: string;
isEVM?: boolean;
imageLink?: string;
}

export const AddressBox = ({ address, isEVM, imageLink }: AddressBoxProps) => {
export const AddressBox = ({ address, isEVM }: AddressBoxProps) => {
const { t } = useTranslation();
const theme = useTheme();
const { imageLink } = useMercleNft({ userAddress: address });
const { setSnackbarState } = useMenuStore((state) => state);
const { data: ensName, isSuccess } = useEnsName({
address: address as Address | undefined,
Expand Down Expand Up @@ -96,16 +97,18 @@ export const AddressBox = ({ address, isEVM, imageLink }: AddressBoxProps) => {
<ProfileIconButton onClick={() => handleCopyButton()}>
<ContentCopyIcon sx={{ height: '16px' }} />
</ProfileIconButton>
<a
href={`https://etherscan.io/address/${address}`}
target="_blank"
style={{ textDecoration: 'none', color: 'inherit' }}
rel="noreferrer"
>
<ProfileIconButton>
<OpenInNewIcon sx={{ height: '16px' }} />
</ProfileIconButton>
</a>
{address && (
<a
href={`https://etherscan.io/address/${address}`}
target="_blank"
style={{ textDecoration: 'none', color: 'inherit' }}
rel="noreferrer"
>
<ProfileIconButton>
<OpenInNewIcon sx={{ height: '16px' }} />
</ProfileIconButton>
</a>
)}
</AddressDisplayBox>
</AddressBoxContainer>
);
Expand Down
1 change: 1 addition & 0 deletions src/components/ProfilePage/Common/IconHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const IconHeader = ({ tooltipKey, title }: IconHeaderProps) => {
{title}
<Tooltip
title={t(tooltipKey as any)}
sx={{ cursor: 'help' }}
placement="top"
enterTouchDelay={0}
arrow
Expand Down
8 changes: 4 additions & 4 deletions src/components/ProfilePage/LevelBox/LevelIndicator.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { LevelButton } from '../../Button';
import { NoSelectTypography } from '../ProfilePage.style';
import { XPIcon } from '../../illustrations/XPIcon';
import { NoSelectTypography } from '../ProfilePage.style';

interface LevelButtonProps {
level: number;
points: number;
bound: number;
}

export const LevelIndicator = ({ level, points }: LevelButtonProps) => {
export const LevelIndicator = ({ level, bound }: LevelButtonProps) => {
return (
<LevelButton aria-label="XP Level" size="medium">
<NoSelectTypography
Expand All @@ -16,7 +16,7 @@ export const LevelIndicator = ({ level, points }: LevelButtonProps) => {
fontWeight={600}
marginRight="8px"
>
LEVEL {level} • {points}
LEVEL {level} • {bound}
</NoSelectTypography>
<XPIcon size={16} />
</LevelButton>
Expand Down
Loading
Loading