diff --git a/libs/model/src/services/openai/generateTokenIdea.ts b/libs/model/src/services/openai/generateTokenIdea.ts index 5da2d146440..b0a6165b688 100644 --- a/libs/model/src/services/openai/generateTokenIdea.ts +++ b/libs/model/src/services/openai/generateTokenIdea.ts @@ -136,6 +136,7 @@ const generateTokenIdea = async function* ({ const imageResponse = await openai.images.generate({ prompt: TOKEN_AI_PROMPTS_CONFIG.image(tokenIdea.name, tokenIdea.symbol), size: '256x256', + model: 'dall-e-2', n: 1, response_format: 'url', }); diff --git a/packages/commonwealth/client/assets/img/TwitterspaceGrowlImage.png b/packages/commonwealth/client/assets/img/TwitterspaceGrowlImage.png deleted file mode 100644 index da123670136..00000000000 Binary files a/packages/commonwealth/client/assets/img/TwitterspaceGrowlImage.png and /dev/null differ diff --git a/packages/commonwealth/client/scripts/helpers/feature-flags.ts b/packages/commonwealth/client/scripts/helpers/feature-flags.ts index 8ecf6879237..20d6778b20d 100644 --- a/packages/commonwealth/client/scripts/helpers/feature-flags.ts +++ b/packages/commonwealth/client/scripts/helpers/feature-flags.ts @@ -32,6 +32,7 @@ const featureFlags = { referrals: buildFlag(process.env.FLAG_REFERRALS), stickyEditor: buildFlag(process.env.FLAG_STICKY_EDITOR), newMobileNav: buildFlag(process.env.FLAG_NEW_MOBILE_NAV), + rewardsPage: buildFlag(process.env.FLAG_REWARDS_PAGE), }; export type AvailableFeatureFlag = keyof typeof featureFlags; diff --git a/packages/commonwealth/client/scripts/navigation/CommonDomainRoutes.tsx b/packages/commonwealth/client/scripts/navigation/CommonDomainRoutes.tsx index 55bab393a6b..384c5910256 100644 --- a/packages/commonwealth/client/scripts/navigation/CommonDomainRoutes.tsx +++ b/packages/commonwealth/client/scripts/navigation/CommonDomainRoutes.tsx @@ -117,6 +117,8 @@ const CommunityNotFoundPage = lazy( () => import('views/pages/CommunityNotFoundPage'), ); +const RewardsPage = lazy(() => import('views/pages/RewardsPage')); + const CommonDomainRoutes = ({ tokenizedCommunityEnabled, }: RouteFeatureFlags) => [ @@ -180,6 +182,11 @@ const CommonDomainRoutes = ({ type: 'common', })} />, + , import('views/pages/new_profile')); const EditNewProfilePage = lazy(() => import('views/pages/edit_new_profile')); const ProfilePageRedirect = lazy(() => import('views/pages/profile_redirect')); +const RewardsPage = lazy(() => import('views/pages/RewardsPage')); + const CustomDomainRoutes = ({ tokenizedCommunityEnabled, }: RouteFeatureFlags) => { @@ -177,6 +179,11 @@ const CustomDomainRoutes = ({ path="/myTransactions" element={withLayout(MyTransactions, { type: 'common' })} />, + , // NOTIFICATIONS { )} {children} -
- setIsVisible(!isVisible)} + ( +
+ handleIconClick({ + e, + isMenuOpen: isVisible, + isTooltipOpen, + handleInteraction, + onClick: () => setIsVisible(!isVisible), + }) + } + onMouseEnter={(e) => { + handleMouseEnter({ + e, + isMenuOpen: isVisible, + handleInteraction, + }); + }} + onMouseLeave={(e) => { + handleMouseLeave({ + e, + isTooltipOpen, + handleInteraction, + }); + }} + > + setIsVisible(!isVisible)} + /> +
+ )} /> + { const location = useLocation(); const user = useUserStore(); const newMobileNav = useFlag('newMobileNav'); + const rewardsEnabled = useFlag('rewardsPage'); const [isDrawerOpen, setIsDrawerOpen] = useState(false); @@ -56,6 +57,15 @@ const MobileNavigation = () => { }, ] : []), + ...(user.isLoggedIn && rewardsEnabled + ? [ + { + type: 'rewards' as const, + onClick: () => navigate('/rewards', {}, null), + selected: !!matchRoutes([{ path: '/rewards' }], location), + }, + ] + : []), ]; return ( diff --git a/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/NavigationButton.scss b/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/NavigationButton.scss index d936f8f5b3f..f2608b97a06 100644 --- a/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/NavigationButton.scss +++ b/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/NavigationButton.scss @@ -6,8 +6,7 @@ flex-direction: column; justify-content: center; align-items: center; - padding: 4px 16px 0; - min-width: 80px; + padding: 4px 8px 0; svg { fill: $neutral-600; diff --git a/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/NavigationButton.tsx b/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/NavigationButton.tsx index ec5deb8c379..0b745af7b8e 100644 --- a/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/NavigationButton.tsx +++ b/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/NavigationButton.tsx @@ -7,7 +7,7 @@ import { typeToIconAndName } from './utils'; import './NavigationButton.scss'; export interface NavigationButtonProps { - type: 'home' | 'create' | 'explore' | 'notifications'; + type: 'home' | 'create' | 'explore' | 'notifications' | 'rewards'; selected: boolean; onClick: () => void; } diff --git a/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/utils.ts b/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/utils.ts index b94d12090ce..b3badcfc3df 100644 --- a/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/utils.ts +++ b/packages/commonwealth/client/scripts/views/components/MobileNavigation/NavigationButton/utils.ts @@ -17,5 +17,7 @@ export const typeToIconAndName = ( return ['compassPhosphor', 'Explore']; case 'notifications': return ['bell', 'Notifications']; + case 'rewards': + return ['cardholder', 'Rewards']; } }; diff --git a/packages/commonwealth/client/scripts/views/components/SublayoutHeader/DesktopHeader/DesktopHeader.scss b/packages/commonwealth/client/scripts/views/components/SublayoutHeader/DesktopHeader/DesktopHeader.scss index 2e6527b0f80..7e75f2c78c8 100644 --- a/packages/commonwealth/client/scripts/views/components/SublayoutHeader/DesktopHeader/DesktopHeader.scss +++ b/packages/commonwealth/client/scripts/views/components/SublayoutHeader/DesktopHeader/DesktopHeader.scss @@ -55,6 +55,31 @@ margin-bottom: auto; margin-left: 5px; } + + .rewards-button { + margin-left: 24px; + display: flex; + align-items: center; + justify-content: center; + + svg { + fill: $neutral-500; + } + + .rewards-button-container { + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + + .earnings { + margin-left: 4px; + font-family: $font-family-roboto; + color: $neutral-500; + white-space: nowrap; + } + } + } } .DesktopMenuContainer { diff --git a/packages/commonwealth/client/scripts/views/components/SublayoutHeader/DesktopHeader/DesktopHeader.tsx b/packages/commonwealth/client/scripts/views/components/SublayoutHeader/DesktopHeader/DesktopHeader.tsx index c5f1478c132..8751e07d37b 100644 --- a/packages/commonwealth/client/scripts/views/components/SublayoutHeader/DesktopHeader/DesktopHeader.tsx +++ b/packages/commonwealth/client/scripts/views/components/SublayoutHeader/DesktopHeader/DesktopHeader.tsx @@ -15,10 +15,13 @@ import { HelpMenuPopover } from 'views/menus/help_menu'; import UserDropdown from './UserDropdown'; +import { useFlag } from 'hooks/useFlag'; import { useFetchCustomDomainQuery } from 'state/api/configuration'; import useUserStore from 'state/ui/user'; import AuthButtons from 'views/components/SublayoutHeader/AuthButtons'; import { AuthModalType } from 'views/modals/AuthModal'; +import { capDecimals } from 'views/modals/ManageCommunityStakeModal/utils'; +import { CWText } from '../../component_kit/cw_text'; import './DesktopHeader.scss'; interface DesktopHeaderProps { @@ -28,6 +31,7 @@ interface DesktopHeaderProps { const DesktopHeader = ({ onMobile, onAuthModalOpen }: DesktopHeaderProps) => { const navigate = useCommonNavigate(); + const rewardsEnabled = useFlag('rewardsPage'); const { menuVisible, setMenu, menuName, setUserToggledVisibility } = useSidebarStore(); const user = useUserStore(); @@ -118,7 +122,41 @@ const DesktopHeader = ({ onMobile, onAuthModalOpen }: DesktopHeaderProps) => {
- {user.isLoggedIn && } + {user.isLoggedIn && ( + <> + + + {rewardsEnabled && ( +
+ ( +
navigate('/rewards', {}, null)} + onMouseEnter={handleInteraction} + onMouseLeave={handleInteraction} + > + + + {capDecimals('0.125')} ETH + +
+ )} + /> +
+ )} + + )} {user.isLoggedIn && ( diff --git a/packages/commonwealth/client/scripts/views/components/SublayoutHeader/useUserMenuItems.tsx b/packages/commonwealth/client/scripts/views/components/SublayoutHeader/useUserMenuItems.tsx index 1c193c365fd..03969ec2edd 100644 --- a/packages/commonwealth/client/scripts/views/components/SublayoutHeader/useUserMenuItems.tsx +++ b/packages/commonwealth/client/scripts/views/components/SublayoutHeader/useUserMenuItems.tsx @@ -32,6 +32,8 @@ import { } from 'views/components/component_kit/cw_toggle'; import CWIconButton from 'views/components/component_kit/new_designs/CWIconButton'; import useAuthentication from '../../modals/AuthModal/useAuthentication'; +import { MobileTabType } from '../../pages/RewardsPage/types'; +import { mobileTabParam } from '../../pages/RewardsPage/utils'; import { useCommunityStake } from '../CommunityStake'; import UserMenuItem from './UserMenuItem'; import useCheckAuthenticatedAddresses from './useCheckAuthenticatedAddresses'; @@ -87,6 +89,7 @@ const useUserMenuItems = ({ recheck: isMenuOpen, }); + const rewardsEnabled = useFlag('rewardsPage'); const referralsEnabled = useFlag('referrals'); const userData = useUserStore(); @@ -297,7 +300,14 @@ const useUserMenuItems = ({ { type: 'default', label: 'My transactions', - onClick: () => navigate(`/myTransactions`, {}, null), + onClick: () => + navigate( + rewardsEnabled + ? `/rewards?tab=${mobileTabParam[MobileTabType.WalletBalance]}` + : `/myTransactions`, + {}, + null, + ), }, { type: 'default', diff --git a/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts b/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts index 879ea97a752..fcadd7ecfd8 100644 --- a/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts +++ b/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts @@ -13,6 +13,7 @@ import { BellSimpleSlash, BookOpenText, Brain, + Cardholder, CaretDoubleLeft, CaretDoubleRight, CaretDown, @@ -89,6 +90,7 @@ import { Trash, Trophy, TwitterLogo, + UserSwitch, Users, UsersThree, Warning, @@ -147,6 +149,7 @@ export const iconLookup = { bellRinging: withPhosphorIcon(BellSimpleRinging), bellMuted: withPhosphorIcon(BellSimpleSlash), bookOpenText: withPhosphorIcon(BookOpenText), + cardholder: withPhosphorIcon(Cardholder), cautionCircle: Icons.CWCautionCircle, cautionTriangle: Icons.CWCautionTriangle, chatDots: withPhosphorIcon(ChatDots), @@ -286,6 +289,7 @@ export const iconLookup = { unsubscribe: Icons.CWUnsubscribe, upvote: withPhosphorIcon(ArrowFatUp), users: withPhosphorIcon(Users), + userSwitch: withPhosphorIcon(UserSwitch), vote: Icons.CWVote, views: Icons.CWViews, wallet: Icons.CWWallet, diff --git a/packages/commonwealth/client/scripts/views/pages/404.tsx b/packages/commonwealth/client/scripts/views/pages/404.tsx index 6dd88ffc867..e761a264eb3 100644 --- a/packages/commonwealth/client/scripts/views/pages/404.tsx +++ b/packages/commonwealth/client/scripts/views/pages/404.tsx @@ -39,7 +39,7 @@ export const PageNotFound = (props: PageNotFoundProps) => { navigate('/dashboard/for-you')} + onClick={() => navigate('/dashboard/for-you', {}, null)} /> )} void; + children?: React.ReactNode; +} + +const RewardsCard = ({ + title, + description, + icon, + onSeeAllClick, + children, +}: RewardsCardProps) => { + return ( + +
+ + + {title} + + {onSeeAllClick && ( + + See all + + )} +
+ {description && ( + + {description} + + )} +
{children}
+
+ ); +}; + +export default RewardsCard; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsCard/index.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsCard/index.ts new file mode 100644 index 00000000000..2d9516a1554 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsCard/index.ts @@ -0,0 +1,3 @@ +import RewardsCard from './RewardsCard'; + +export default RewardsCard; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsPage.scss b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsPage.scss new file mode 100644 index 00000000000..e59345de4a6 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsPage.scss @@ -0,0 +1,34 @@ +@import '../../../styles/shared'; + +.RewardsPage { + display: flex; + flex-direction: column; + width: 100%; + gap: 16px; + + .rewards-card-container { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; + + @include smallInclusive { + grid-template-columns: 1fr; + } + } + + .rewards-button-tabs { + display: none; + gap: 8px; + overflow-x: auto; + padding-bottom: 8px; + + @include smallInclusive { + display: flex; + } + } + + .rewards-tab-container { + width: 100%; + overflow-x: auto; + } +} diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsPage.tsx b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsPage.tsx new file mode 100644 index 00000000000..ebe3b039949 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsPage.tsx @@ -0,0 +1,104 @@ +import React, { useState } from 'react'; + +import useBrowserWindow from 'hooks/useBrowserWindow'; +import { useFlag } from 'hooks/useFlag'; +import { useCommonNavigate } from 'navigation/helpers'; +import useUserStore from 'state/ui/user'; +import { IconName } from 'views/components/component_kit/cw_icons/cw_icon_lookup'; + +import { CWText } from '../../components/component_kit/cw_text'; +import CWPageLayout from '../../components/component_kit/new_designs/CWPageLayout'; +import { + CWTab, + CWTabsRow, +} from '../../components/component_kit/new_designs/CWTabs'; +import { PageNotFound } from '../404'; +import RewardsTab from './RewardsTab'; +import { QuestCard, ReferralCard, WalletCard } from './cards'; +import { QuestTable, ReferralTable, WalletTable } from './tables'; +import { MobileTabType, TableType } from './types'; +import { getInitialTab, mobileTabParam, tabToTable, typeToIcon } from './utils'; + +import './RewardsPage.scss'; + +const RewardsPage = () => { + const navigate = useCommonNavigate(); + const user = useUserStore(); + const rewardsEnabled = useFlag('rewardsPage'); + + const [mobileTab, setMobileTab] = useState(getInitialTab()); + const [tableTab, setTableTab] = useState(tabToTable[getInitialTab()]); + + const handleTabChange = (type: MobileTabType) => { + setMobileTab(type); + setTableTab(tabToTable[type]); + navigate(`?tab=${mobileTabParam[type]}`, { replace: true }); + }; + + const { isWindowSmallInclusive } = useBrowserWindow({}); + + if (!user.isLoggedIn || !rewardsEnabled) { + return ; + } + + return ( + +
+ + Rewards + + + {/* visible only on mobile */} +
+ {Object.values(MobileTabType).map((type) => ( + handleTabChange(type)} + /> + ))} +
+ + {/* on mobile show only one card */} +
+ {(!isWindowSmallInclusive || + mobileTab === MobileTabType.Referrals) && ( + handleTabChange(MobileTabType.Referrals)} + /> + )} + {(!isWindowSmallInclusive || + mobileTab === MobileTabType.WalletBalance) && } + {(!isWindowSmallInclusive || mobileTab === MobileTabType.Quests) && ( + handleTabChange(MobileTabType.Quests)} + /> + )} +
+ +
+ + {Object.values(TableType).map((type) => ( + { + setTableTab(type); + }} + /> + ))} + +
+ + {tableTab === TableType.Referrals && } + {tableTab === TableType.TokenTXHistory && } + {tableTab === TableType.XPEarnings && } +
+
+ ); +}; + +export default RewardsPage; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsTab/RewardsTab.scss b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsTab/RewardsTab.scss new file mode 100644 index 00000000000..5f29d46cbfc --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsTab/RewardsTab.scss @@ -0,0 +1,37 @@ +@import '../../../../styles/shared'; + +.RewardsTab { + display: flex; + align-items: center; + gap: 8px; + cursor: pointer; + outline: none; + border: 1px solid $neutral-700; + padding: 10px 16px; + border-radius: 6px; + + .Text { + white-space: nowrap; + } + + svg { + fill: $neutral-700; + } + + &.isActive { + border-color: $primary-600; + + svg { + fill: $primary-600; + } + + .Text { + color: $primary-600; + } + } + + &:focus, + &:active { + outline: none; + } +} diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsTab/RewardsTab.tsx b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsTab/RewardsTab.tsx new file mode 100644 index 00000000000..59eac28f707 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsTab/RewardsTab.tsx @@ -0,0 +1,28 @@ +import clsx from 'clsx'; +import React from 'react'; + +import { CWIcon } from 'views/components/component_kit/cw_icons/cw_icon'; +import { IconName } from 'views/components/component_kit/cw_icons/cw_icon_lookup'; +import { CWText } from 'views/components/component_kit/cw_text'; + +import './RewardsTab.scss'; + +interface RewardsTabProps { + icon: IconName; + title: string; + isActive: boolean; + onClick: () => void; +} + +const RewardsTab = ({ icon, title, isActive, onClick }: RewardsTabProps) => { + return ( + + ); +}; + +export default RewardsTab; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsTab/index.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsTab/index.ts new file mode 100644 index 00000000000..b724ce97aae --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/RewardsTab/index.ts @@ -0,0 +1,3 @@ +import RewardsTab from './RewardsTab'; + +export default RewardsTab; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/QuestCard/QuestCard.scss b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/QuestCard/QuestCard.scss new file mode 100644 index 00000000000..59f3826a58b --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/QuestCard/QuestCard.scss @@ -0,0 +1,2 @@ +.QuestCard { +} diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/QuestCard/QuestCard.tsx b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/QuestCard/QuestCard.tsx new file mode 100644 index 00000000000..6c61da192b1 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/QuestCard/QuestCard.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +import RewardsCard from '../../RewardsCard'; + +import './QuestCard.scss'; + +interface QuestCardProps { + onSeeAllClick: () => void; +} + +const QuestCard = ({ onSeeAllClick }: QuestCardProps) => { + return ( + +
Quest Card Body
+
+ ); +}; + +export default QuestCard; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/QuestCard/index.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/QuestCard/index.ts new file mode 100644 index 00000000000..2d9f756b160 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/QuestCard/index.ts @@ -0,0 +1,3 @@ +import QuestCard from './QuestCard'; + +export default QuestCard; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/ReferralCard/ReferralCard.scss b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/ReferralCard/ReferralCard.scss new file mode 100644 index 00000000000..98b25a011b6 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/ReferralCard/ReferralCard.scss @@ -0,0 +1,2 @@ +.ReferralCard { +} diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/ReferralCard/ReferralCard.tsx b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/ReferralCard/ReferralCard.tsx new file mode 100644 index 00000000000..a50fe70f79b --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/ReferralCard/ReferralCard.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +import RewardsCard from '../../RewardsCard'; + +import './ReferralCard.scss'; + +interface ReferralCardProps { + onSeeAllClick: () => void; +} + +const ReferralCard = ({ onSeeAllClick }: ReferralCardProps) => { + return ( + +
Referral Card Body
+
+ ); +}; + +export default ReferralCard; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/ReferralCard/index.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/ReferralCard/index.ts new file mode 100644 index 00000000000..9f8e05c3a2b --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/ReferralCard/index.ts @@ -0,0 +1,3 @@ +import ReferralCard from './ReferralCard'; + +export default ReferralCard; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/WalletCard/WalletCard.scss b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/WalletCard/WalletCard.scss new file mode 100644 index 00000000000..06dc2bdad4e --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/WalletCard/WalletCard.scss @@ -0,0 +1,2 @@ +.WalletCard { +} diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/WalletCard/WalletCard.tsx b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/WalletCard/WalletCard.tsx new file mode 100644 index 00000000000..ef449b2f9a3 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/WalletCard/WalletCard.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +import RewardsCard from '../../RewardsCard'; + +import './WalletCard.scss'; + +const WalletCard = () => { + return ; +}; + +export default WalletCard; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/WalletCard/index.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/WalletCard/index.ts new file mode 100644 index 00000000000..9f6dd229c48 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/WalletCard/index.ts @@ -0,0 +1,3 @@ +import WalletCard from './WalletCard'; + +export default WalletCard; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/index.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/index.ts new file mode 100644 index 00000000000..b3d1ee00d26 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/cards/index.ts @@ -0,0 +1,5 @@ +import QuestCard from './QuestCard'; +import ReferralCard from './ReferralCard'; +import WalletCard from './WalletCard'; + +export { QuestCard, ReferralCard, WalletCard }; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/index.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/index.ts new file mode 100644 index 00000000000..4f7c38da991 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/index.ts @@ -0,0 +1 @@ +export { default } from './RewardsPage'; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/QuestTable/QuestTable.scss b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/QuestTable/QuestTable.scss new file mode 100644 index 00000000000..04f685f3dac --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/QuestTable/QuestTable.scss @@ -0,0 +1,2 @@ +.QuestTable { +} diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/QuestTable/QuestTable.tsx b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/QuestTable/QuestTable.tsx new file mode 100644 index 00000000000..ec6d30ce355 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/QuestTable/QuestTable.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +import './QuestTable.scss'; + +export const QuestTable = () => { + return
Quest Table
; +}; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/QuestTable/index.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/QuestTable/index.ts new file mode 100644 index 00000000000..1dc4520d731 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/QuestTable/index.ts @@ -0,0 +1 @@ +export * from './QuestTable'; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/ReferralTable/ReferralTable.scss b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/ReferralTable/ReferralTable.scss new file mode 100644 index 00000000000..cbade9bf34b --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/ReferralTable/ReferralTable.scss @@ -0,0 +1,2 @@ +.ReferralTable { +} diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/ReferralTable/ReferralTable.tsx b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/ReferralTable/ReferralTable.tsx new file mode 100644 index 00000000000..215d6652db7 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/ReferralTable/ReferralTable.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +import './ReferralTable.scss'; + +export const ReferralTable = () => { + return
Referral Table
; +}; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/ReferralTable/index.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/ReferralTable/index.ts new file mode 100644 index 00000000000..0dce77ff74c --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/ReferralTable/index.ts @@ -0,0 +1 @@ +export * from './ReferralTable'; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/WalletTable/WalletTable.scss b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/WalletTable/WalletTable.scss new file mode 100644 index 00000000000..9434b0693fd --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/WalletTable/WalletTable.scss @@ -0,0 +1,2 @@ +.WalletTable { +} diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/WalletTable/WalletTable.tsx b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/WalletTable/WalletTable.tsx new file mode 100644 index 00000000000..8bc3541a5d4 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/WalletTable/WalletTable.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +import './WalletTable.scss'; + +export const WalletTable = () => { + return
Wallet Table
; +}; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/WalletTable/index.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/WalletTable/index.ts new file mode 100644 index 00000000000..107a227cc06 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/WalletTable/index.ts @@ -0,0 +1 @@ +export * from './WalletTable'; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/index.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/index.ts new file mode 100644 index 00000000000..a28267c84c5 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/tables/index.ts @@ -0,0 +1,5 @@ +import { QuestTable } from './QuestTable'; +import { ReferralTable } from './ReferralTable'; +import { WalletTable } from './WalletTable'; + +export { QuestTable, ReferralTable, WalletTable }; diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/types.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/types.ts new file mode 100644 index 00000000000..3e2d83c0972 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/types.ts @@ -0,0 +1,17 @@ +export enum MobileTabType { + Referrals = 'Referrals', + WalletBalance = 'Wallet Balance', + Quests = 'Quests', +} + +export enum TableType { + Referrals = 'Referrals', + TokenTXHistory = 'Token TX History', + XPEarnings = 'XP Earnings', +} + +export const enum TabParam { + referrals = 'referrals', + wallet = 'wallet', + quests = 'quests', +} diff --git a/packages/commonwealth/client/scripts/views/pages/RewardsPage/utils.ts b/packages/commonwealth/client/scripts/views/pages/RewardsPage/utils.ts new file mode 100644 index 00000000000..97e3488bbf1 --- /dev/null +++ b/packages/commonwealth/client/scripts/views/pages/RewardsPage/utils.ts @@ -0,0 +1,36 @@ +import { MobileTabType, TableType, TabParam } from './types'; + +export const getInitialTab = () => { + const params = new URLSearchParams(location.search); + const tabParam = params.get('tab'); + + if (!tabParam) { + return MobileTabType.Referrals; + } + + return tabParamToMobileTab[tabParam]; +}; + +export const tabParamToMobileTab = { + [TabParam.referrals]: MobileTabType.Referrals, + [TabParam.wallet]: MobileTabType.WalletBalance, + [TabParam.quests]: MobileTabType.Quests, +}; + +export const mobileTabParam = { + [MobileTabType.Referrals]: 'referrals', + [MobileTabType.WalletBalance]: 'wallet', + [MobileTabType.Quests]: 'quests', +}; + +export const tabToTable = { + [MobileTabType.Referrals]: TableType.Referrals, + [MobileTabType.WalletBalance]: TableType.TokenTXHistory, + [MobileTabType.Quests]: TableType.XPEarnings, +}; + +export const typeToIcon = { + [MobileTabType.Referrals]: 'userSwitch', + [MobileTabType.WalletBalance]: 'cardholder', + [MobileTabType.Quests]: 'trophy', +}; diff --git a/packages/commonwealth/client/vite.config.ts b/packages/commonwealth/client/vite.config.ts index 01594e63d8b..8c990ddd8c5 100644 --- a/packages/commonwealth/client/vite.config.ts +++ b/packages/commonwealth/client/vite.config.ts @@ -47,6 +47,7 @@ export default defineConfig(({ mode }) => { env.FLAG_MANAGE_API_KEYS, ), 'process.env.FLAG_REFERRALS': JSON.stringify(env.FLAG_REFERRALS), + 'process.env.FLAG_REWARDS_PAGE': JSON.stringify(env.FLAG_REWARDS_PAGE), 'process.env.FLAG_STICKY_EDITOR': JSON.stringify(env.FLAG_STICKY_EDITOR), 'process.env.FLAG_NEW_MOBILE_NAV': JSON.stringify(env.FLAG_NEW_MOBILE_NAV), }; diff --git a/packages/commonwealth/package.json b/packages/commonwealth/package.json index 74678bc6223..421b2ed7f38 100644 --- a/packages/commonwealth/package.json +++ b/packages/commonwealth/package.json @@ -182,7 +182,7 @@ "cosmjs-types": "0.8.0", "crypto-browserify": "^3.12.0", "discord.js": "^14.16.2", - "dompurify": "^2.2.6", + "dompurify": "^2.5.8", "dotenv": "^16.0.3", "esm-loader-css": "^1.0.6", "ethereumjs-util": "7.1.0", diff --git a/packages/commonwealth/server/migrations/20241219235431-convert-gov-gen-addresses.js b/packages/commonwealth/server/migrations/20241219235431-convert-gov-gen-addresses.js new file mode 100644 index 00000000000..421baf010d2 --- /dev/null +++ b/packages/commonwealth/server/migrations/20241219235431-convert-gov-gen-addresses.js @@ -0,0 +1,56 @@ +'use strict'; + +const { bech32 } = require('bech32'); + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.sequelize.transaction(async (transaction) => { + const existingAtoneAddresses = await queryInterface.sequelize.query( + ` + SELECT address, user_id + FROM "Addresses" + WHERE community_id = 'atomone' AND address LIKE 'atone%'; + `, + { type: Sequelize.QueryTypes.SELECT, transaction }, + ); + + const addresses = await queryInterface.sequelize.query( + ` + SELECT address, user_id + FROM "Addresses" + WHERE community_id = 'atomone' AND address LIKE 'govgen%'; + `, + { type: Sequelize.QueryTypes.SELECT, transaction }, + ); + + for (const address of addresses) { + const { words } = bech32.decode(address.address); + const encodedAddress = bech32.encode('atone', words); + + if (existingAtoneAddresses.find((a) => a.address === encodedAddress)) + continue; + + await queryInterface.sequelize.query( + ` + UPDATE "Addresses" + SET address = '${encodedAddress}' + WHERE address = '${address.address}' AND community_id = 'atomone'; + `, + { transaction }, + ); + } + + await queryInterface.sequelize.query( + ` + UPDATE "Addresses" + SET role = 'admin' + WHERE address = 'atone13zarqk8gm2sl6ctaxgc50sq6gvnew359fp3ecf' AND community_id = 'atomone'; + `, + { transaction }, + ); + }); + }, + + async down(queryInterface, Sequelize) {}, +}; diff --git a/packages/commonwealth/server/routes/generateImage.ts b/packages/commonwealth/server/routes/generateImage.ts index af502f18c5c..5ec76c309c2 100644 --- a/packages/commonwealth/server/routes/generateImage.ts +++ b/packages/commonwealth/server/routes/generateImage.ts @@ -57,10 +57,10 @@ const generateImage = async ( let image; try { const response = await openai.images.generate({ - model: 'dall-e-3', + model: 'dall-e-2', n: 1, prompt: description, - size: '512x512', + size: '256x256', response_format: 'url', }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 354a5e0a72b..d22c2ec8f06 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1101,8 +1101,8 @@ importers: specifier: ^14.16.2 version: 14.16.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) dompurify: - specifier: ^2.2.6 - version: 2.5.2 + specifier: ^2.5.8 + version: 2.5.8 dotenv: specifier: ^16.0.3 version: 16.4.5 @@ -10204,8 +10204,8 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - dompurify@2.5.2: - resolution: {integrity: sha512-5vSyvxRAb45EoWwAktUT3AYqAwXK4FL7si22Cgj46U6ICsj/YJczCN+Bk7WNABIQmpWRymGfslMhrRUZkQNnqA==} + dompurify@2.5.8: + resolution: {integrity: sha512-o1vSNgrmYMQObbSSvF/1brBYEQPHhV1+gsmrusO7/GXtp1T9rCS8cXFqVxK/9crT1jA6Ccv+5MTSjBNqr7Sovw==} domutils@1.5.1: resolution: {integrity: sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==} @@ -32183,7 +32183,7 @@ snapshots: dependencies: domelementtype: 2.3.0 - dompurify@2.5.2: {} + dompurify@2.5.8: {} domutils@1.5.1: dependencies: