AlbyEarn.tsx raw

   1  import {
   2    ExternalLinkIcon,
   3    HeartIcon,
   4    LucideIcon,
   5    TrophyIcon,
   6  } from "lucide-react";
   7  import AppHeader from "src/components/AppHeader";
   8  import ExternalLink from "src/components/ExternalLink";
   9  import { Alert, AlertDescription, AlertTitle } from "src/components/ui/alert";
  10  import { Card, CardContent } from "src/components/ui/card";
  11  
  12  import albyExtension from "src/assets/suggested-apps/alby-extension.png";
  13  import albyGo from "src/assets/suggested-apps/alby-go.png";
  14  import alby from "src/assets/suggested-apps/alby.png";
  15  import { FormattedBitcoinAmount } from "src/components/FormattedBitcoinAmount";
  16  
  17  interface Platform {
  18    name: string;
  19    url: string;
  20  }
  21  
  22  interface EarnOpportunity {
  23    title: string;
  24    logo: string;
  25    rewardSat?: number;
  26    rewardText?: string;
  27    rewardIcon?: LucideIcon;
  28    platforms: Platform[];
  29  }
  30  
  31  const earnOpportunities: EarnOpportunity[] = [
  32    {
  33      title: "Alby Referral Program",
  34      logo: alby,
  35      rewardText: "10% of subscription revenue",
  36      rewardIcon: TrophyIcon,
  37      platforms: [
  38        {
  39          name: "getalby.com/referrals",
  40          url: "https://getalby.com/referrals",
  41        },
  42      ],
  43    },
  44    {
  45      title: "Alby Go",
  46      logo: albyGo,
  47      rewardSat: 1000,
  48      platforms: [
  49        {
  50          name: "Google Play",
  51          url: "https://play.google.com/store/apps/details?id=com.getalby.mobile",
  52        },
  53        {
  54          name: "App Store",
  55          url: "https://apps.apple.com/app/alby-go/id6476033149",
  56        },
  57      ],
  58    },
  59    {
  60      title: "Alby Extension",
  61      logo: albyExtension,
  62      rewardSat: 1000,
  63      platforms: [
  64        {
  65          name: "Chrome",
  66          url: "https://chrome.google.com/webstore/detail/alby-bitcoin-wallet-for-l/iokeahhehimjnekafflcihljlcjccdbe",
  67        },
  68        {
  69          name: "Firefox",
  70          url: "https://addons.mozilla.org/en-US/firefox/addon/alby/",
  71        },
  72      ],
  73    },
  74    {
  75      title: "Alby",
  76      logo: alby,
  77      rewardText: "Our gratitude",
  78      rewardIcon: HeartIcon,
  79      platforms: [
  80        {
  81          name: "Trustpilot",
  82          url: "https://www.trustpilot.com/review/getalby.com",
  83        },
  84      ],
  85    },
  86  ];
  87  
  88  function Reward({ opportunity }: { opportunity: EarnOpportunity }) {
  89    if (opportunity.rewardSat !== undefined) {
  90      return (
  91        <FormattedBitcoinAmount
  92          amountMsat={opportunity.rewardSat * 1000}
  93          className="text-lg font-semibold tabular-nums"
  94        />
  95      );
  96    }
  97  
  98    if (opportunity.rewardText && opportunity.rewardIcon) {
  99      const Icon = opportunity.rewardIcon;
 100      return (
 101        <span className="inline-flex items-center gap-1.5 text-sm text-muted-foreground">
 102          <Icon className="size-4" />
 103          {opportunity.rewardText}
 104        </span>
 105      );
 106    }
 107  
 108    return null;
 109  }
 110  
 111  export function AlbyEarn() {
 112    return (
 113      <>
 114        <AppHeader
 115          title="Earn"
 116          description="Earn bitcoin by referring new users or leaving a review."
 117          pageTitle="Earn"
 118        />
 119        <div className="space-y-6">
 120          <Alert>
 121            <TrophyIcon className="h-4 w-4" />
 122            <AlertTitle>Claim your reward</AlertTitle>
 123            <AlertDescription className="inline">
 124              Review one of our products and email your review link or screenshot
 125              to{" "}
 126              <ExternalLink
 127                to="mailto:support@getalby.com"
 128                className="underline font-medium"
 129              >
 130                support@getalby.com
 131              </ExternalLink>{" "}
 132              to claim your reward.
 133            </AlertDescription>
 134          </Alert>
 135  
 136          <Card>
 137            <CardContent>
 138              <div className="divide-y">
 139                {earnOpportunities.map((opportunity) => (
 140                  <div
 141                    key={opportunity.title}
 142                    className="flex items-center gap-4 py-5 first:pt-0 last:pb-0"
 143                  >
 144                    <img
 145                      src={opportunity.logo}
 146                      className="size-10 md:size-12 rounded-lg shrink-0"
 147                      alt={opportunity.title}
 148                    />
 149                    <div className="flex flex-1 flex-col sm:flex-row sm:items-center gap-2 min-w-0">
 150                      <div className="flex-1 min-w-0">
 151                        <div className="font-medium">{opportunity.title}</div>
 152                        <div className="text-sm text-muted-foreground flex flex-wrap items-center gap-x-2">
 153                          {opportunity.platforms.map((platform, index) => (
 154                            <span
 155                              key={index}
 156                              className="inline-flex items-center"
 157                            >
 158                              {index > 0 && <span className="mr-2">•</span>}
 159                              <ExternalLink
 160                                to={platform.url}
 161                                className="underline text-foreground inline-flex items-center hover:text-muted-foreground"
 162                              >
 163                                {platform.name}
 164                                <ExternalLinkIcon className="size-3 ml-1" />
 165                              </ExternalLink>
 166                            </span>
 167                          ))}
 168                        </div>
 169                      </div>
 170                      <div className="sm:text-right shrink-0">
 171                        <Reward opportunity={opportunity} />
 172                      </div>
 173                    </div>
 174                  </div>
 175                ))}
 176              </div>
 177            </CardContent>
 178          </Card>
 179        </div>
 180      </>
 181    );
 182  }
 183