Skip to content

Commit

Permalink
Merge pull request #8700 from hicommonwealth/marcin/7661/farcaster-ui
Browse files Browse the repository at this point in the history
UI for Farcaster
  • Loading branch information
masvelio authored Aug 7, 2024
2 parents 79c70a9 + 1a5763f commit 89e556e
Show file tree
Hide file tree
Showing 17 changed files with 464 additions and 170 deletions.
9 changes: 9 additions & 0 deletions packages/commonwealth/client/assets/img/farcaster.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const featureFlags = {
knockPushNotifications: buildFlag(
process.env.FLAG_KNOCK_PUSH_NOTIFICATIONS_ENABLED,
),
farcasterContest: buildFlag(process.env.FLAG_FARCASTER_CONTEST),
};

export type AvailableFeatureFlag = keyof typeof featureFlags;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@
}
}

.type-selection-list {
display: flex;
flex-direction: column;
gap: 16px;

.empty-img {
min-width: 50px;
}
}

.list-container {
display: flex;
flex-direction: column;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import React from 'react';
import React, { useState } from 'react';

import commonUrl from 'assets/img/branding/common.svg';
import farcasterUrl from 'assets/img/farcaster.svg';
import useAppStatus from 'hooks/useAppStatus';
import { useBrowserAnalyticsTrack } from 'hooks/useBrowserAnalyticsTrack';
import { useFlag } from 'hooks/useFlag';
import { useCommonNavigate } from 'navigation/helpers';
import {
BaseMixpanelPayload,
MixpanelContestEvents,
} from 'shared/analytics/types';
import app from 'state';
import useGetFeeManagerBalanceQuery from 'state/api/communityStake/getFeeManagerBalance';
import Permissions from 'utils/Permissions';
Expand All @@ -9,19 +18,19 @@ import { CWText } from 'views/components/component_kit/cw_text';
import { CWButton } from 'views/components/component_kit/new_designs/CWButton';
import CWPageLayout from 'views/components/component_kit/new_designs/CWPageLayout';
import { PageNotFound } from 'views/pages/404';
import EmptyCard from 'views/pages/CommunityManagement/Contests/EmptyContestsList/EmptyCard';

import { useBrowserAnalyticsTrack } from 'client/scripts/hooks/useBrowserAnalyticsTrack';
import useAppStatus from 'hooks/useAppStatus';
import {
BaseMixpanelPayload,
MixpanelContestEvents,
} from 'shared/analytics/types';
import ContestsList from '../ContestsList';
import { ContestType, ContestView } from '../types';
import useCommunityContests from '../useCommunityContests';
import './AdminContestsPage.scss';
import FeeManagerBanner from './FeeManagerBanner';

import './AdminContestsPage.scss';

const AdminContestsPage = () => {
const farcasterContestEnabled = useFlag('farcasterContest');
const [contestView, setContestView] = useState<ContestView>(ContestView.List);

const navigate = useCommonNavigate();

const { isAddedToHomeScreen } = useAppStatus();
Expand Down Expand Up @@ -55,7 +64,10 @@ const AdminContestsPage = () => {
event: MixpanelContestEvents.CREATE_CONTEST_BUTTON_PRESSED,
isPWA: isAddedToHomeScreen,
});
navigate('/manage/contests/launch');

return farcasterContestEnabled
? setContestView(ContestView.TypeSelection)
: navigate('/manage/contests/launch');
};

if (!app.isLoggedIn() || !isAdmin) {
Expand All @@ -71,7 +83,7 @@ const AdminContestsPage = () => {
<div className="admin-header-row">
<CWText type="h2">Contests</CWText>

{stakeEnabled && (
{stakeEnabled && contestView !== ContestView.TypeSelection && (
<CWButton
iconLeft="plusPhosphor"
label="Create contest"
Expand All @@ -80,21 +92,55 @@ const AdminContestsPage = () => {
)}
</div>

{showBanner && (
<FeeManagerBanner
feeManagerBalance={feeManagerBalance}
isLoading={isFeeManagerBalanceLoading}
/>
{contestView === ContestView.List ? (
<>
{showBanner && (
<FeeManagerBanner
feeManagerBalance={feeManagerBalance}
isLoading={isFeeManagerBalanceLoading}
/>
)}

<ContestsList
contests={contestsData}
isLoading={isContestDataLoading}
isAdmin={isAdmin}
isContestAvailable={isContestAvailable}
stakeEnabled={stakeEnabled}
feeManagerBalance={feeManagerBalance}
onSetContestSelectionView={() =>
setContestView(ContestView.TypeSelection)
}
/>
</>
) : (
<div className="type-selection-list">
<EmptyCard
img={commonUrl}
title="Launch on Common"
subtitle="lorem ipsum dolor sit amet"
button={{
label: 'Launch Common contest',
handler: () =>
navigate(
`/manage/contests/launch?type=${ContestType.Common}`,
),
}}
/>
<EmptyCard
img={farcasterUrl}
title="Launch on Farcaster"
subtitle="lorem ipsum dolor sit amet"
button={{
label: 'Launch Farcaster contest',
handler: () =>
navigate(
`/manage/contests/launch?type=${ContestType.Farcaster}`,
),
}}
/>
</div>
)}

<ContestsList
contests={contestsData}
isLoading={isContestDataLoading}
isAdmin={isAdmin}
isContestAvailable={isContestAvailable}
stakeEnabled={stakeEnabled}
feeManagerBalance={feeManagerBalance}
/>
</div>
</CWPageLayout>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,36 @@
}
}
}

.farcaster-cta {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
gap: 7px;
padding-block: 8px;
border: 1px solid $neutral-200;
border-radius: 6px;
margin-top: 8px;

&:hover {
cursor: pointer;
background-color: $neutral-25;
}

&:active {
background-color: $neutral-50;
}

&:focus {
outline: none;
}

img {
width: 32px;
height: 32px;
}
}
}

.contest-footer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import clsx from 'clsx';
import moment from 'moment';
import React from 'react';

import farcasterUrl from 'assets/img/farcaster.svg';
import useBrowserWindow from 'hooks/useBrowserWindow';
import useRerender from 'hooks/useRerender';
import { useCommonNavigate } from 'navigation/helpers';
Expand Down Expand Up @@ -60,6 +61,7 @@ interface ContestCardProps {
isRecurring: boolean;
showShareButton?: boolean;
isHorizontal?: boolean;
isFarcaster?: boolean;
}

const ContestCard = ({
Expand All @@ -78,6 +80,7 @@ const ContestCard = ({
isRecurring,
showShareButton = true,
isHorizontal = false,
isFarcaster = false,
}: ContestCardProps) => {
const navigate = useCommonNavigate();
const user = useUserStore();
Expand Down Expand Up @@ -144,6 +147,10 @@ const ContestCard = ({
onFund?.();
};

const handleFarcasterClick = () => {
console.log('Frame copied!');
};

const balance = isRecurring
? feeManagerBalance
: String(oneOffContestBalance);
Expand Down Expand Up @@ -251,7 +258,17 @@ const ContestCard = ({
/>
)}
</div>

{isFarcaster && (
<button className="farcaster-cta" onClick={handleFarcasterClick}>
<img src={farcasterUrl} alt="farcaster" />
<CWText type="h5" fontWeight="bold">
Copy Farcaster Frame
</CWText>
</button>
)}
</div>

{isAdmin && (
<div className="contest-footer">
<CWDivider />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface ContestsListProps {
stakeEnabled: boolean;
isContestAvailable: boolean;
feeManagerBalance?: string;
onSetContestSelectionView?: () => void;
}
const ContestsList = ({
contests,
Expand All @@ -53,6 +54,7 @@ const ContestsList = ({
stakeEnabled,
isContestAvailable,
feeManagerBalance,
onSetContestSelectionView,
}: ContestsListProps) => {
const [fundDrawerAddress, setFundDrawerAddress] = useState('');

Expand All @@ -73,6 +75,7 @@ const ContestsList = ({
<EmptyContestsList
isStakeEnabled={stakeEnabled}
isContestAvailable={isContestAvailable}
onSetContestSelectionView={onSetContestSelectionView}
/>
) : (
contests.map((contest) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ import { useCommonNavigate } from 'navigation/helpers';

import EmptyCard from './EmptyCard';

import { useFlag } from 'hooks/useFlag';
import './EmptyContestsList.scss';

interface EmptyContestsListProps {
isStakeEnabled: boolean;
isContestAvailable: boolean;
onSetContestSelectionView?: () => void;
}

const EmptyContestsList = ({
isStakeEnabled,
isContestAvailable,
onSetContestSelectionView,
}: EmptyContestsListProps) => {
const navigate = useCommonNavigate();
const farcasterContestEnabled = useFlag('farcasterContest');

return (
<div className="EmptyContestsList">
Expand All @@ -38,7 +42,10 @@ const EmptyContestsList = ({
subtitle="Setting up a contest just takes a few minutes and can be a huge boost to your community."
button={{
label: 'Launch a contest',
handler: () => navigate('/manage/contests/launch'),
handler: () =>
farcasterContestEnabled
? onSetContestSelectionView?.()
: navigate('/manage/contests/launch'),
}}
/>
) : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ const ManageContest = ({ contestAddress }: ManageContestProps) => {

case 'ContestLive':
return (
<ContestLiveStep createdContestAddress={createdContestAddress} />
<ContestLiveStep
createdContestAddress={createdContestAddress}
isFarcasterContest={!!contestFormData?.farcasterContestDuration}
/>
);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ import './ContestLiveStep.scss';

interface ContestLiveStepProps {
createdContestAddress: string;
isFarcasterContest: boolean;
}

const ContestLiveStep = ({ createdContestAddress }: ContestLiveStepProps) => {
const ContestLiveStep = ({
createdContestAddress,
isFarcasterContest,
}: ContestLiveStepProps) => {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);

const navigate = useCommonNavigate();
Expand Down Expand Up @@ -45,8 +49,14 @@ const ContestLiveStep = ({ createdContestAddress }: ContestLiveStepProps) => {
/>
<CWButton
containerClassName="cta-btn"
label="Go to contests"
onClick={() => navigate('/manage/contests')}
label={
isFarcasterContest ? 'Copy Farcaster Frame' : 'Go to contests'
}
onClick={() =>
isFarcasterContest
? console.log('Farcaster frame copied')
: navigate('/manage/contests')
}
/>
</div>
</div>
Expand Down
Loading

0 comments on commit 89e556e

Please sign in to comment.