Skip to content

Commit 5550b16

Browse files
authored
feat: init shop (#50)
1 parent 31f435a commit 5550b16

File tree

5 files changed

+259
-4
lines changed

5 files changed

+259
-4
lines changed

lark-ui/src/lib/BottomNavigation.svelte

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
if (!page) return 'create';
1717
if (page.startsWith('/app/projects')) return 'create';
1818
if (page.startsWith('/app/explore')) return 'explore';
19+
if (page.startsWith('/app/shop')) return 'shop';
1920
if (page.startsWith('/app/settings')) return 'settings';
2021
return 'create';
2122
});
@@ -46,7 +47,7 @@
4647
}
4748
4849
function navigateTo(tab: string) {
49-
if (tab === 'shop') {
50+
if (tab === 'shop' && onboarding) {
5051
handleLockedClick(tab);
5152
return;
5253
}
@@ -62,6 +63,9 @@
6263
case 'shop':
6364
goto('/app/shop');
6465
break;
66+
case 'settings':
67+
goto('/app/settings');
68+
break;
6569
}
6670
}
6771
@@ -93,17 +97,17 @@
9397
Explore
9498
</button>
9599
<button
96-
class="nav-item {true ? 'disabled' : 'enabled'}"
100+
class="nav-item {onboarding ? 'disabled' : 'enabled'}"
97101
class:active={activeTab === 'shop'}
98102
class:shake={shakingTab === 'shop'}
99103
onclick={() => navigateTo('shop')}
100104
role="tab"
101105
aria-selected={activeTab === 'shop'}
102106
>
103107
Shop
104-
<!-- {#if onboarding} -->
108+
{#if onboarding}
105109
<img class="lock" src="/icons/lock.svg" alt="Lock" />
106-
<!-- {/if} -->
110+
{/if}
107111
</button>
108112
</div>
109113
<div class="tray">
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<script lang="ts">
2+
import { onMount } from "svelte";
3+
import { goto } from "$app/navigation";
4+
import { checkAuthStatus, recalculateHourCounts, updateUser, type User } from "$lib/auth";
5+
import ShopCard from "./ShopCard.svelte";
6+
import { shopData } from "./shop";
7+
8+
let user: User | null = $state<User | null>(null);
9+
10+
onMount(async () => {
11+
user = await checkAuthStatus();
12+
13+
if (!user) {
14+
goto("/");
15+
return;
16+
}
17+
});
18+
</script>
19+
20+
<div class="shop-page">
21+
<h1 class="page-title">SHOP</h1>
22+
<h2 class="page-subtitle">Click on a shop item to view it.</h2>
23+
24+
<div class="grid grid-cols-4 w-full px-[3vw] gap-x-[3vw] gap-y-[6vh] pb-[10vh] text-[#fee1c0]">
25+
{#each shopData as item}
26+
<ShopCard index={item.index} name={item.name} img={item.img} requiredHours={item.requiredHours} desc={item.desc} />
27+
{/each}
28+
</div>
29+
</div>
30+
31+
<style>
32+
.shop-page {
33+
position: relative;
34+
min-height: 100vh;
35+
background: #453b61;
36+
padding: 57px 50px 200px;
37+
}
38+
39+
.page-title {
40+
font-family: "Moga", sans-serif;
41+
font-size: 90px;
42+
color: white;
43+
letter-spacing: -0.99px;
44+
margin: 0;
45+
line-height: 1;
46+
}
47+
48+
.page-subtitle {
49+
font-family: "PT Serif", serif;
50+
font-weight: bold;
51+
font-size: 30px;
52+
color: white;
53+
letter-spacing: -0.99px;
54+
margin: 0;
55+
line-height: 1.5;
56+
padding-bottom: 32px;
57+
}
58+
59+
.details {
60+
display: flex;
61+
flex-direction: column;
62+
gap: 16px;
63+
64+
width: min(100%, 400px);
65+
}
66+
67+
.details-header {
68+
font-family: "PT Serif", sans-serif;
69+
font-size: 32px;
70+
font-weight: 700;
71+
color: white;
72+
}
73+
74+
.details-label {
75+
font-family: "PT Sans", sans-serif;
76+
font-size: 16px;
77+
font-weight: 400;
78+
color: white;
79+
}
80+
81+
.details-input {
82+
font-family: "PT Sans", sans-serif;
83+
font-size: 16px;
84+
font-weight: 400;
85+
color: white;
86+
background: #3b3153;
87+
border: none;
88+
padding: 8px;
89+
border-radius: 4px;
90+
color-scheme: dark;
91+
}
92+
</style>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script lang="ts">
2+
const { index, name, img, desc, requiredHours }: {
3+
index: number;
4+
name: string;
5+
desc: string;
6+
img: string;
7+
requiredHours: number | null;
8+
} = $props();
9+
</script>
10+
11+
<a
12+
href={`/app/shop/${index}`}
13+
class="group cursor-pointer rounded-[2vh] gap-[1vh] flex flex-col s-center text-center transition-all no-select"
14+
>
15+
<div
16+
class="bg-[#5E5087] p-[2vh] border border-black rounded-[2vh] shadow-lg transition-all duration-200 ease-out group-hover:rotate-[2deg] group-hover:shadow-2xl group-hover:scale-[1.1]"
17+
>
18+
<img
19+
src={img}
20+
alt={name}
21+
class="rounded-[1.5vh] mb-[1vh] w-full h-[25vh] object-cover border-2 border-black transition-all duration-200 ease-out no-select"
22+
draggable="false"
23+
/>
24+
<div class="flex s-center justify-center no-select">
25+
<p>{requiredHours ? `${requiredHours} hours needed` : 'Free'}</p>
26+
</div>
27+
</div>
28+
29+
<div
30+
class="bg-[#5E5087] px-[0] py-[1vh] w-full border border-black rounded-[2vh] shadow-lg transition-all duration-200 ease-out group-hover:-rotate-[3deg] group-hover:shadow-2xl group-hover:scale-[1.05]"
31+
>
32+
<h3 class="text-[3vh] font-bold font-['PT_Serif',_serif] border-b border-black pb-[0.5vh] px-[1vw] line-clamp-2 overflow-hidden text-ellipsis break-words">
33+
{name}
34+
</h3>
35+
<p class="text-[2vh] opacity-80 pt-[0.5vh] px-[1vw] line-clamp-2 overflow-hidden text-ellipsis">{desc}</p>
36+
</div>
37+
</a>
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<script lang="ts">
2+
import { onMount } from "svelte";
3+
import { goto } from "$app/navigation";
4+
import { checkAuthStatus, recalculateHourCounts, updateUser, type User } from "$lib/auth";
5+
import ShopCard from "../ShopCard.svelte";
6+
import { page } from "$app/state";
7+
import Button from "$lib/Button.svelte";
8+
import { shopData } from "../shop";
9+
10+
let user: User | null = $state<User | null>(null);
11+
12+
const index = parseInt(page.params.id!);
13+
14+
onMount(async () => {
15+
user = await checkAuthStatus();
16+
17+
if (!user) {
18+
goto("/");
19+
return;
20+
}
21+
});
22+
</script>
23+
24+
<div class="shop-page">
25+
<div class="back-button">
26+
<Button label={'← Back to Shop'} onclick={() => goto("/app/shop")} color='black' />
27+
</div>
28+
<div class="item-overview">
29+
<div class="flex flex-col items-stretch justify-center">
30+
<img
31+
src={shopData[index].img}
32+
alt={shopData[index].name}
33+
class="rounded-[1.5vh] mb-[1vh] w-[400px] object-cover border-2 border-black no-select"
34+
draggable="false"
35+
/>
36+
</div>
37+
<div class="item-content">
38+
<div class="item-inner">
39+
<h1 class="item-name">{shopData[index].name}</h1>
40+
<h2 class="req-hours">{shopData[index].requiredHours} hours</h2>
41+
<p class="item-desc">{shopData[index].desc}</p>
42+
</div>
43+
<div>
44+
<Button label="Coming Soon" disabled />
45+
</div>
46+
</div>
47+
</div>
48+
</div>
49+
50+
<style>
51+
.shop-page {
52+
position: relative;
53+
min-height: 100vh;
54+
background: #453b61;
55+
padding: 57px 50px 200px;
56+
}
57+
58+
.item-overview {
59+
display: flex;
60+
align-items: stretch;
61+
62+
gap: 48px;
63+
64+
min-height: 600px;
65+
}
66+
67+
.item-content {
68+
display: flex;
69+
flex-direction: column;
70+
justify-content: space-between;
71+
72+
min-height: 100%;
73+
}
74+
75+
.item-name {
76+
font-family: "Moga", sans-serif;
77+
font-size: 90px;
78+
color: white;
79+
letter-spacing: -0.99px;
80+
margin: 0;
81+
line-height: 1;
82+
max-width: 750px;
83+
}
84+
85+
.req-hours {
86+
font-family: "PT Serif", serif;
87+
font-size: 40px;
88+
color: white;
89+
letter-spacing: -0.99px;
90+
margin-bottom: 30px;
91+
line-height: 1;
92+
max-width: 750px;
93+
}
94+
95+
.item-desc {
96+
font-family: "PT Sans", sans-serif;
97+
font-size: 24px;
98+
color: white;
99+
font-weight: normal;
100+
letter-spacing: -0.99px;
101+
margin: 0;
102+
line-height: 1;
103+
max-width: 750px;
104+
}
105+
106+
.back-button {
107+
margin-bottom: 30px;
108+
position: sticky;
109+
top: 57px;
110+
z-index: 10;
111+
}
112+
113+
</style>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export const shopData = [
2+
{
3+
index: 0,
4+
name: "Ticket to Midnight",
5+
desc: "This is your ticket into Midnight!",
6+
img: "https://hc-cdn.hel1.your-objectstorage.com/s/v3/f032dd343a3b09de55ec1b7bf3be1637e9abc633_image.png",
7+
requiredHours: 50,
8+
},
9+
];

0 commit comments

Comments
 (0)