kopia lustrzana https://github.com/bugout-dev/moonstream
Merge pull request #575 from bugout-dev/mixpanel-improvements
tracking on landing buttonspull/470/head
commit
9dff3ab721
|
|
@ -34,10 +34,7 @@ import { v4 as uuidv4 } from "uuid";
|
||||||
import RouteButton from "../src/components/RouteButton";
|
import RouteButton from "../src/components/RouteButton";
|
||||||
import { MODAL_TYPES } from "../src/core/providers/OverlayProvider/constants";
|
import { MODAL_TYPES } from "../src/core/providers/OverlayProvider/constants";
|
||||||
import mixpanel from "mixpanel-browser";
|
import mixpanel from "mixpanel-browser";
|
||||||
import {
|
import { MIXPANEL_EVENTS } from "../src/core/providers/AnalyticsProvider/constants";
|
||||||
MIXPANEL_PROPS,
|
|
||||||
MIXPANEL_EVENTS,
|
|
||||||
} from "../src/core/providers/AnalyticsProvider/constants";
|
|
||||||
|
|
||||||
const SplitWithImage = dynamic(
|
const SplitWithImage = dynamic(
|
||||||
() => import("../src/components/SplitWithImage"),
|
() => import("../src/components/SplitWithImage"),
|
||||||
|
|
@ -144,6 +141,8 @@ const assets = {
|
||||||
game7io: `${AWS_ASSETS_PATH}/featured_by/game7io_logo.png`,
|
game7io: `${AWS_ASSETS_PATH}/featured_by/game7io_logo.png`,
|
||||||
orangedao: `${AWS_ASSETS_PATH}/featured_by/orangedao_logo.png`,
|
orangedao: `${AWS_ASSETS_PATH}/featured_by/orangedao_logo.png`,
|
||||||
meetup: `${AWS_ASSETS_PATH}/featured_by/meetup_logo.png`,
|
meetup: `${AWS_ASSETS_PATH}/featured_by/meetup_logo.png`,
|
||||||
|
gnosis: `${AWS_ASSETS_PATH}/gnosis_chain_logo_no_text.png`,
|
||||||
|
immutable: `${AWS_ASSETS_PATH}/immutable_x_logo.png`,
|
||||||
};
|
};
|
||||||
|
|
||||||
const carousel_content = [
|
const carousel_content = [
|
||||||
|
|
@ -151,10 +150,8 @@ const carousel_content = [
|
||||||
{ title: "Ethereum", img: assets["ethereumBlackLogo"] },
|
{ title: "Ethereum", img: assets["ethereumBlackLogo"] },
|
||||||
{ title: "Ethereum transaction pool", img: assets["ethereumRainbowLogo"] },
|
{ title: "Ethereum transaction pool", img: assets["ethereumRainbowLogo"] },
|
||||||
{ title: "Polygon", img: assets["maticLogo"] },
|
{ title: "Polygon", img: assets["maticLogo"] },
|
||||||
{ title: "Bitcoin coming soon!", img: assets["bitcoinLogo"] },
|
{ title: "immutable x coming soon!", img: assets["immutable"] },
|
||||||
{ title: "Ethereum", img: assets["ethereumBlackLogo"] },
|
{ title: "gnosis chain coming soon!", img: assets["gnosis"] },
|
||||||
{ title: "Ethereum transaction pool", img: assets["ethereumRainbowLogo"] },
|
|
||||||
{ title: "Polygon", img: assets["maticLogo"] },
|
|
||||||
];
|
];
|
||||||
const Homepage = () => {
|
const Homepage = () => {
|
||||||
const ui = useContext(UIContext);
|
const ui = useContext(UIContext);
|
||||||
|
|
@ -284,6 +281,7 @@ const Homepage = () => {
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
sx={{ scrollBehavior: "smooth" }}
|
sx={{ scrollBehavior: "smooth" }}
|
||||||
bgSize="cover"
|
bgSize="cover"
|
||||||
|
id="page:landing"
|
||||||
>
|
>
|
||||||
<Flex
|
<Flex
|
||||||
direction="column"
|
direction="column"
|
||||||
|
|
@ -589,10 +587,9 @@ const Homepage = () => {
|
||||||
<GridItem
|
<GridItem
|
||||||
px="7%"
|
px="7%"
|
||||||
mt={["32px", "64px", null]}
|
mt={["32px", "64px", null]}
|
||||||
pt={["98px", "126px", null]}
|
py={["98px", "128px", null]}
|
||||||
colSpan="12"
|
colSpan="12"
|
||||||
bgColor="blue.50"
|
bgColor="blue.50"
|
||||||
pb={["20px", "30px", "92px", null, "92px", "196px"]}
|
|
||||||
>
|
>
|
||||||
<Heading {...HEADING_PROPS} textAlign="center" pb={14} pt={0}>
|
<Heading {...HEADING_PROPS} textAlign="center" pb={14} pt={0}>
|
||||||
Trusted by{" "}
|
Trusted by{" "}
|
||||||
|
|
@ -653,10 +650,6 @@ const Homepage = () => {
|
||||||
cta={{
|
cta={{
|
||||||
colorScheme: "orange",
|
colorScheme: "orange",
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
mixpanel.get_distinct_id() &&
|
|
||||||
mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
|
||||||
[`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Early access CTA: developer txpool button`,
|
|
||||||
});
|
|
||||||
router.push("/whitepapers");
|
router.push("/whitepapers");
|
||||||
},
|
},
|
||||||
label: "NFT market report",
|
label: "NFT market report",
|
||||||
|
|
@ -857,10 +850,9 @@ const Homepage = () => {
|
||||||
<GridItem
|
<GridItem
|
||||||
px="7%"
|
px="7%"
|
||||||
mt={["32px", "64px", null]}
|
mt={["32px", "64px", null]}
|
||||||
pt={["98px", "226px", null]}
|
py={["98px", "128px", null]}
|
||||||
colSpan="12"
|
colSpan="12"
|
||||||
bgColor="blue.50"
|
bgColor="blue.50"
|
||||||
pb={["20px", "30px", "92px", null, "92px", "196px"]}
|
|
||||||
>
|
>
|
||||||
<Heading {...HEADING_PROPS} textAlign="center" pb={14} pt={0}>
|
<Heading {...HEADING_PROPS} textAlign="center" pb={14} pt={0}>
|
||||||
Featured by{" "}
|
Featured by{" "}
|
||||||
|
|
@ -912,6 +904,7 @@ const Homepage = () => {
|
||||||
pt={["0", "0", "5.125rem", null, "5.125rem"]}
|
pt={["0", "0", "5.125rem", null, "5.125rem"]}
|
||||||
pb="120px"
|
pb="120px"
|
||||||
px="7%"
|
px="7%"
|
||||||
|
id={"bottom-line"}
|
||||||
>
|
>
|
||||||
<Stack direction="column" justifyContent="center">
|
<Stack direction="column" justifyContent="center">
|
||||||
<chakra.span
|
<chakra.span
|
||||||
|
|
@ -932,33 +925,65 @@ const Homepage = () => {
|
||||||
<Flex direction="row" flexWrap="wrap" placeContent="center">
|
<Flex direction="row" flexWrap="wrap" placeContent="center">
|
||||||
<RouteButton
|
<RouteButton
|
||||||
placeSelf="center"
|
placeSelf="center"
|
||||||
href={`https://github.com/bugout-dev/moonstream`}
|
href={"https://discord.gg/K56VNUQGvA"}
|
||||||
size="md"
|
size="lg"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
w="250px"
|
leftIcon={<FaDiscord />}
|
||||||
|
w="280px"
|
||||||
|
onClick={() => {
|
||||||
|
if (mixpanel.get_distinct_id()) {
|
||||||
|
mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
||||||
|
full_url: router.nextRouter.asPath,
|
||||||
|
buttonName: `Join our Discord`,
|
||||||
|
page: `landing`,
|
||||||
|
section: `bottom-line`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Join our Discord
|
||||||
|
</RouteButton>
|
||||||
|
<RouteButton
|
||||||
|
// mt={3}
|
||||||
|
// p={8}
|
||||||
|
placeSelf="center"
|
||||||
|
href={`https://github.com/bugout-dev/moonstream`}
|
||||||
|
size="lg"
|
||||||
|
variant="outline"
|
||||||
|
colorScheme="blue"
|
||||||
|
w="280px"
|
||||||
|
onClick={() => {
|
||||||
|
if (mixpanel.get_distinct_id()) {
|
||||||
|
mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
||||||
|
full_url: router.nextRouter.asPath,
|
||||||
|
buttonName: `git clone moonstream`,
|
||||||
|
page: `landing`,
|
||||||
|
section: `bottom-line`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
leftIcon={<FaGithubSquare />}
|
leftIcon={<FaGithubSquare />}
|
||||||
>
|
>
|
||||||
git clone moonstream
|
git clone moonstream
|
||||||
</RouteButton>
|
</RouteButton>
|
||||||
<RouteButton
|
|
||||||
placeSelf="center"
|
|
||||||
href={"https://discord.gg/K56VNUQGvA"}
|
|
||||||
size="md"
|
|
||||||
variant="outline"
|
|
||||||
colorScheme="blue"
|
|
||||||
leftIcon={<FaDiscord />}
|
|
||||||
w="250px"
|
|
||||||
>
|
|
||||||
Join our Discord
|
|
||||||
</RouteButton>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
<Button
|
<Button
|
||||||
mt={3}
|
// mt={3}
|
||||||
placeSelf="center"
|
placeSelf="center"
|
||||||
w={["100%", "100%", "fit-content", null]}
|
w={["100%", "100%", "fit-content", null]}
|
||||||
maxW={["250px", null, "fit-content"]}
|
maxW={["280px", null, "fit-content"]}
|
||||||
onClick={() => toggleModal({ type: MODAL_TYPES.SIGNUP })}
|
onClick={() => {
|
||||||
|
if (mixpanel.get_distinct_id()) {
|
||||||
|
mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
||||||
|
full_url: router.nextRouter.asPath,
|
||||||
|
buttonName: `sign up`,
|
||||||
|
page: `landing`,
|
||||||
|
section: `bottom-line`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
toggleModal({ type: MODAL_TYPES.SIGNUP });
|
||||||
|
}}
|
||||||
size="lg"
|
size="lg"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
colorScheme="orange"
|
colorScheme="orange"
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,15 @@
|
||||||
import React, { useContext } from "react";
|
import React from "react";
|
||||||
import { useStatus } from "../../src/core/hooks";
|
import { useStatus } from "../../src/core/hooks";
|
||||||
import { Heading, Text, Flex, Spacer, chakra, Spinner } from "@chakra-ui/react";
|
import { Heading, Text, Flex, Spacer, chakra, Spinner } from "@chakra-ui/react";
|
||||||
import { getLayout, getLayoutProps } from "../../src/layouts/InfoPageLayout";
|
import { getLayout, getLayoutProps } from "../../src/layouts/InfoPageLayout";
|
||||||
import UserContext from "../../src/core/providers/UserProvider/context";
|
|
||||||
|
|
||||||
const Status = () => {
|
const Status = () => {
|
||||||
const user = useContext(UserContext);
|
|
||||||
const healthyStatusText = "Available";
|
const healthyStatusText = "Available";
|
||||||
const downStatusText = "Unavailable";
|
const downStatusText = "Unavailable";
|
||||||
const unauthorizedText = "Please login";
|
|
||||||
const healthyStatusColor = "green.900";
|
const healthyStatusColor = "green.900";
|
||||||
const downStatusColor = "red.600";
|
const downStatusColor = "red.600";
|
||||||
|
|
||||||
const shortTimestamp = (rawTimestamp) => {
|
const { serverListStatusCache } = useStatus();
|
||||||
return rawTimestamp.replace(/^.+T/, "").replace(/\..+/, "");
|
|
||||||
};
|
|
||||||
|
|
||||||
const {
|
|
||||||
serverListStatusCache,
|
|
||||||
} = useStatus();
|
|
||||||
|
|
||||||
console.log(serverListStatusCache?.data);
|
console.log(serverListStatusCache?.data);
|
||||||
|
|
||||||
|
|
@ -223,20 +214,14 @@ const Status = () => {
|
||||||
: downStatusText}
|
: downStatusText}
|
||||||
</Text>
|
</Text>
|
||||||
</StatusRow>
|
</StatusRow>
|
||||||
<StatusRow
|
<StatusRow title="Ethereum latest block" cache={serverListStatusCache}>
|
||||||
title="Ethereum latest block"
|
|
||||||
cache={serverListStatusCache}
|
|
||||||
>
|
|
||||||
<Text>
|
<Text>
|
||||||
{dbServerStatus?.response?.ethereum_block_latest
|
{dbServerStatus?.response?.ethereum_block_latest
|
||||||
? dbServerStatus.response.ethereum_block_latest
|
? dbServerStatus.response.ethereum_block_latest
|
||||||
: 0}
|
: 0}
|
||||||
</Text>
|
</Text>
|
||||||
</StatusRow>
|
</StatusRow>
|
||||||
<StatusRow
|
<StatusRow title="Polygon latest block" cache={serverListStatusCache}>
|
||||||
title="Polygon latest block"
|
|
||||||
cache={serverListStatusCache}
|
|
||||||
>
|
|
||||||
<Text>
|
<Text>
|
||||||
{dbServerStatus?.response?.polygon_block_latest
|
{dbServerStatus?.response?.polygon_block_latest
|
||||||
? dbServerStatus.response.polygon_block_latest
|
? dbServerStatus.response.polygon_block_latest
|
||||||
|
|
@ -246,7 +231,10 @@ const Status = () => {
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<StatusRow title="Database replica server" cache={serverListStatusCache}>
|
<StatusRow
|
||||||
|
title="Database replica server"
|
||||||
|
cache={serverListStatusCache}
|
||||||
|
>
|
||||||
<Text
|
<Text
|
||||||
color={
|
color={
|
||||||
dbReplicaServerStatus?.status_code == 200
|
dbReplicaServerStatus?.status_code == 200
|
||||||
|
|
@ -259,20 +247,14 @@ const Status = () => {
|
||||||
: downStatusText}
|
: downStatusText}
|
||||||
</Text>
|
</Text>
|
||||||
</StatusRow>
|
</StatusRow>
|
||||||
<StatusRow
|
<StatusRow title="Ethereum latest block" cache={serverListStatusCache}>
|
||||||
title="Ethereum latest block"
|
|
||||||
cache={serverListStatusCache}
|
|
||||||
>
|
|
||||||
<Text>
|
<Text>
|
||||||
{dbReplicaServerStatus?.response?.ethereum_block_latest
|
{dbReplicaServerStatus?.response?.ethereum_block_latest
|
||||||
? dbReplicaServerStatus.response.ethereum_block_latest
|
? dbReplicaServerStatus.response.ethereum_block_latest
|
||||||
: 0}
|
: 0}
|
||||||
</Text>
|
</Text>
|
||||||
</StatusRow>
|
</StatusRow>
|
||||||
<StatusRow
|
<StatusRow title="Polygon latest block" cache={serverListStatusCache}>
|
||||||
title="Polygon latest block"
|
|
||||||
cache={serverListStatusCache}
|
|
||||||
>
|
|
||||||
<Text>
|
<Text>
|
||||||
{dbReplicaServerStatus?.response?.polygon_block_latest
|
{dbReplicaServerStatus?.response?.polygon_block_latest
|
||||||
? dbReplicaServerStatus.response.polygon_block_latest
|
? dbReplicaServerStatus.response.polygon_block_latest
|
||||||
|
|
@ -282,7 +264,10 @@ const Status = () => {
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<StatusRow title="Unim Leaderboard server" cache={serverListStatusCache}>
|
<StatusRow
|
||||||
|
title="Unim Leaderboard server"
|
||||||
|
cache={serverListStatusCache}
|
||||||
|
>
|
||||||
<Text
|
<Text
|
||||||
color={
|
color={
|
||||||
unimLeaderboardStatus?.status_code == 200
|
unimLeaderboardStatus?.status_code == 200
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ const SignUp = ({ toggleModal }) => {
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
placeholder="Your username here"
|
placeholder="Your username here"
|
||||||
name="username"
|
name="username"
|
||||||
|
autoComplete="username"
|
||||||
ref={register({ required: "Username is required!" })}
|
ref={register({ required: "Username is required!" })}
|
||||||
/>
|
/>
|
||||||
<InputRightElement>
|
<InputRightElement>
|
||||||
|
|
@ -57,6 +58,7 @@ const SignUp = ({ toggleModal }) => {
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
placeholder="Your email here"
|
placeholder="Your email here"
|
||||||
name="email"
|
name="email"
|
||||||
|
autoComplete="email"
|
||||||
ref={register({ required: "Email is required!" })}
|
ref={register({ required: "Email is required!" })}
|
||||||
/>
|
/>
|
||||||
<InputRightElement>
|
<InputRightElement>
|
||||||
|
|
@ -71,6 +73,7 @@ const SignUp = ({ toggleModal }) => {
|
||||||
<PasswordInput
|
<PasswordInput
|
||||||
placeholder="Add password"
|
placeholder="Add password"
|
||||||
name="password"
|
name="password"
|
||||||
|
autoComplete="new-password"
|
||||||
ref={register({ required: "Password is required!" })}
|
ref={register({ required: "Password is required!" })}
|
||||||
/>
|
/>
|
||||||
<FormErrorMessage color="red.400" pl="1">
|
<FormErrorMessage color="red.400" pl="1">
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,9 @@ import React, { useContext } from "react";
|
||||||
import UIContext from "../core/providers/UIProvider/context";
|
import UIContext from "../core/providers/UIProvider/context";
|
||||||
import { FaDiscord, FaGithubSquare } from "react-icons/fa";
|
import { FaDiscord, FaGithubSquare } from "react-icons/fa";
|
||||||
import RouteButton from "../components/RouteButton";
|
import RouteButton from "../components/RouteButton";
|
||||||
|
import mixpanel from "mixpanel-browser";
|
||||||
|
import MIXPANEL_EVENTS from "../core/providers/AnalyticsProvider/constants";
|
||||||
|
import { useRouter } from "../core/hooks";
|
||||||
|
|
||||||
const Feature = ({ text, icon, iconBg, bullets }) => {
|
const Feature = ({ text, icon, iconBg, bullets }) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -72,6 +75,8 @@ const SplitWithImage = ({
|
||||||
imgBoxShadow,
|
imgBoxShadow,
|
||||||
py,
|
py,
|
||||||
}) => {
|
}) => {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
var buttonSize = useBreakpointValue({
|
var buttonSize = useBreakpointValue({
|
||||||
base: { single: "sm", double: "xs" },
|
base: { single: "sm", double: "xs" },
|
||||||
sm: { single: "md", double: "sm" },
|
sm: { single: "md", double: "sm" },
|
||||||
|
|
@ -186,6 +191,16 @@ const SplitWithImage = ({
|
||||||
w={["100%", "100%", "fit-content", null]}
|
w={["100%", "100%", "fit-content", null]}
|
||||||
maxW={["250px", null, "fit-content"]}
|
maxW={["250px", null, "fit-content"]}
|
||||||
href={socialButton.url}
|
href={socialButton.url}
|
||||||
|
onClick={() => {
|
||||||
|
if (mixpanel.get_distinct_id()) {
|
||||||
|
mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
||||||
|
full_url: router.nextRouter.asPath,
|
||||||
|
buttonName: `${socialButton.title}`,
|
||||||
|
page: `splitWImage`,
|
||||||
|
section: `${badge}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
mt={[0, 0, null, 16]}
|
mt={[0, 0, null, 16]}
|
||||||
size={socialButton ? buttonSize.double : buttonSize.single}
|
size={socialButton ? buttonSize.double : buttonSize.single}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|
@ -206,7 +221,18 @@ const SplitWithImage = ({
|
||||||
variant="outline"
|
variant="outline"
|
||||||
mt={[0, 0, null, 16]}
|
mt={[0, 0, null, 16]}
|
||||||
size={socialButton ? buttonSize.double : buttonSize.single}
|
size={socialButton ? buttonSize.double : buttonSize.single}
|
||||||
onClick={cta.onClick}
|
onClick={() => {
|
||||||
|
if (mixpanel.get_distinct_id()) {
|
||||||
|
mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
||||||
|
full_url: router.nextRouter.asPath,
|
||||||
|
buttonName: `${cta.label}`,
|
||||||
|
page: `splitWImage`,
|
||||||
|
section: `${badge}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cta.onClick();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{cta.label}
|
{cta.label}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const TrustedBadge = ({
|
||||||
}) => {
|
}) => {
|
||||||
const _scale = scale ?? 1;
|
const _scale = scale ?? 1;
|
||||||
return (
|
return (
|
||||||
<LinkBox m={2}>
|
<LinkBox m={2} bgColor="blue.300" borderRadius="md">
|
||||||
<LinkOverlay href={boxURL} isExternal>
|
<LinkOverlay href={boxURL} isExternal>
|
||||||
<Flex
|
<Flex
|
||||||
m={1}
|
m={1}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import { useClientID, useUser, useRouter } from "../../hooks";
|
||||||
import { MIXPANEL_EVENTS, MIXPANEL_PROPS } from "./constants";
|
import { MIXPANEL_EVENTS, MIXPANEL_PROPS } from "./constants";
|
||||||
import UIContext from "../UIProvider/context";
|
import UIContext from "../UIProvider/context";
|
||||||
|
|
||||||
|
const TELEMETRY_SCHEMA_VERSION = 1.0;
|
||||||
|
|
||||||
const AnalyticsProvider = ({ children }) => {
|
const AnalyticsProvider = ({ children }) => {
|
||||||
const clientID = useClientID();
|
const clientID = useClientID();
|
||||||
const analytics = process.env.NEXT_PUBLIC_MIXPANEL_TOKEN;
|
const analytics = process.env.NEXT_PUBLIC_MIXPANEL_TOKEN;
|
||||||
|
|
@ -138,6 +140,7 @@ const AnalyticsProvider = ({ children }) => {
|
||||||
loaded: () => {
|
loaded: () => {
|
||||||
setIsLoaded(true);
|
setIsLoaded(true);
|
||||||
mixpanel.identify(clientID);
|
mixpanel.identify(clientID);
|
||||||
|
mixpanel.register({ schema_version: TELEMETRY_SCHEMA_VERSION });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
||||||
Ładowanie…
Reference in New Issue