/ src / lib / components / your-projects-section / your-projects-section.svelte
your-projects-section.svelte
  1  <script lang="ts" context="module">
  2    export const PROJECTS_SECTION_PROJECT_FRAGMENT = gql`
  3      ${PROJECT_CARD_FRAGMENT}
  4      fragment ProjectsSectionProject on Project {
  5        ...ProjectCard
  6      }
  7    `;
  8  </script>
  9  
 10  <script lang="ts">
 11    import PrimaryColorThemer from '../primary-color-themer/primary-color-themer.svelte';
 12    import ProjectCard, { PROJECT_CARD_FRAGMENT } from '../project-card/project-card.svelte';
 13    import Box from '$lib/components/icons/Box.svelte';
 14    import Section from '../section/section.svelte';
 15    import { gql } from 'graphql-request';
 16    import type { ProjectsSectionProjectFragment } from './__generated__/gql.generated';
 17    import isClaimed from '$lib/utils/project/is-claimed';
 18    import Plus from '../icons/Plus.svelte';
 19    import filterCurrentChainData from '$lib/utils/filter-current-chain-data';
 20    import VisibilityToggle from '../visibility-toggle/visibility-toggle.svelte';
 21    import checkIsUser from '$lib/utils/check-is-user';
 22    import walletStore from '$lib/stores/wallet/wallet.store';
 23    import launchClaimProject from '$lib/utils/launch-claim-project';
 24  
 25    export let projects: ProjectsSectionProjectFragment[];
 26    export let withClaimProjectButton = false;
 27    export let showVisibilityToggle = false;
 28    export let label = 'Your projects';
 29  
 30    let error = false;
 31  
 32    export let collapsed = false;
 33    export let collapsable = false;
 34  
 35    let showHidden: boolean = false;
 36    $: hiddenProjectsCount = projects.filter((p) => !p.isVisible).length ?? 0;
 37  
 38    $: visibleProjects = projects.filter((p) => p.isVisible);
 39  
 40    $: hiddenProjects = showHidden ? projects.filter((p) => !p.isVisible) : [];
 41  
 42    $: isOwner = $walletStore.connected && checkIsUser(projects[0]?.chainData[0]?.owner?.accountId);
 43  </script>
 44  
 45  <Section
 46    bind:collapsed
 47    bind:collapsable
 48    header={{
 49      icon: Box,
 50      label,
 51      actions: withClaimProjectButton
 52        ? [
 53            {
 54              label: 'Claim project',
 55              icon: Plus,
 56              handler: () => launchClaimProject(),
 57            },
 58          ]
 59        : [],
 60    }}
 61    skeleton={{
 62      horizontalScroll: false,
 63      loaded: true,
 64      empty: showVisibilityToggle ? projects.length === 0 : visibleProjects.length === 0,
 65      error,
 66      emptyStateEmoji: '🫙',
 67      emptyStateHeadline: 'No claimed projects',
 68      emptyStateText: withClaimProjectButton
 69        ? 'If you develop an open-source project, click "Claim project" to get started.'
 70        : 'This user hasnʼt claimed any software projects yet.',
 71      disconnected: !$walletStore.connected,
 72      disconnectedStateEmoji: '🫙',
 73      disconnectedStateHeadline: 'Connect your wallet',
 74      disconnectedStateText: 'Your claimed projects will show up here when your wallet is connected.',
 75    }}
 76  >
 77    {#if visibleProjects}
 78      <div class="projects">
 79        {#each visibleProjects as project}
 80          {@const projectChainData = filterCurrentChainData(project.chainData)}
 81          {#if isClaimed(projectChainData)}
 82            <div>
 83              <PrimaryColorThemer colorHex={projectChainData.color}>
 84                <ProjectCard {project} isHidden={!project.isVisible} />
 85              </PrimaryColorThemer>
 86            </div>
 87          {/if}
 88        {/each}
 89      </div>
 90    {/if}
 91  
 92    {#if isOwner && showVisibilityToggle}
 93      <VisibilityToggle bind:showHidden hiddenItemsCount={hiddenProjectsCount} />
 94    {/if}
 95  
 96    <div class="projects">
 97      {#each hiddenProjects as project}
 98        {@const projectChainData = filterCurrentChainData(project.chainData)}
 99        {#if isClaimed(projectChainData)}
100          <div>
101            <PrimaryColorThemer colorHex={projectChainData.color}>
102              <ProjectCard {project} isHidden={!project.isVisible} />
103            </PrimaryColorThemer>
104          </div>
105        {/if}
106      {/each}
107    </div>
108  </Section>
109  
110  <style>
111    .projects {
112      display: flex;
113      gap: 1rem;
114      max-width: 100%;
115      position: relative;
116      padding: 2px;
117      flex-wrap: wrap;
118    }
119  
120    .projects > * {
121      width: calc(50% - 0.5rem);
122    }
123  
124    @media (max-width: 560px) {
125      .projects > * {
126        width: 100%;
127        max-width: 100%;
128      }
129    }
130  </style>