Skip to content

Commit d193687

Browse files
authored
Merge pull request #3293 from Voyager-Ship/voyager-ship/improvements
[Refactor]:reward board components
2 parents a84594f + b0cda97 commit d193687

File tree

13 files changed

+297
-79
lines changed

13 files changed

+297
-79
lines changed

app/api/projects/export/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const POST = withAuthRole('hackathonCreator', async (req: NextRequest) =>
88
const buffer = await exportShowcase(body);
99
if (!buffer) {
1010
return NextResponse.json(
11-
{ message: 'no projects found' },
11+
{ message: 'No projects found' },
1212
{ status: 404 }
1313
);
1414
}

components/profile/reward-board/component/auto-rotate-badge.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export function AutoRotateMedal({
4040
return (
4141
<group ref={groupRef}>
4242
<CircularFrame color="#999B9B" />
43-
<ImageDisc url={badgeImage} isUnlocked={!!is_unlocked} Disc={Disc} />
43+
<ImageDisc url={badgeImage} isUnlocked={!!is_unlocked} Disc={Disc} />
4444
<BackFace name={name} description={description} DISC={Disc} />
4545
</group>
4646
);

components/profile/reward-board/component/back-face.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export function BackFace({
2222
const GAP_Y = R * 0.06;
2323

2424
return (
25-
<group rotation={[0, Math.PI, 0]}>
25+
<group rotation={[0, Math.PI, 0]} renderOrder={0}>
2626

2727
<mesh position={[0, 0, -0.010]}>
2828
<circleGeometry args={[plateRadius, DISC.segments]} />
@@ -53,7 +53,9 @@ export function BackFace({
5353
sdfGlyphSize={128}
5454
glyphGeometryDetail={16}
5555
material-toneMapped={false}
56-
56+
material-transparent={false}
57+
material-depthWrite={true}
58+
material-depthTest={true}
5759
onSync={(troika: any) => {
5860

5961
const b = troika.textRenderInfo?.blockBounds;
@@ -85,6 +87,9 @@ export function BackFace({
8587
sdfGlyphSize={128}
8688
glyphGeometryDetail={16}
8789
material-toneMapped={false}
90+
material-transparent={false}
91+
material-depthWrite={true}
92+
material-depthTest={true}
8893
font={fontUrl}
8994
>
9095
{description}

components/profile/reward-board/component/circular-frame.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
export function CircularFrame({ color = "#999B9B" }: { color?: string }) {
22
const FRAME = {
3-
majorRadius: 0.93,
4-
tubeRadius: 0.07,
5-
tubularSegments: 50,
6-
radialSegments: 20,
3+
majorRadius: 1.3,
4+
tubeRadius: 0.09,
5+
tubularSegments: 200,
6+
radialSegments: 200,
77
};
88
return (
99
<mesh>
Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,82 @@
1-
2-
import React, { } from "react";
1+
import React from "react";
32
import { useTexture } from "@react-three/drei";
43
import * as THREE from "three";
54

6-
export function ImageDisc({ url, isUnlocked,Disc }: { url: string; isUnlocked: boolean , Disc: { radius: number; segments: number }}) {
7-
const texture = useTexture(url);
8-
texture.colorSpace = THREE.SRGBColorSpace;
9-
texture.anisotropy = 2;
10-
11-
return (
12-
<mesh position={[0, 0, 0.01]}>
5+
type DiscSpec = { radius: number; segments: number };
6+
7+
export function ImageDisc({
8+
url,
9+
isUnlocked,
10+
Disc,
11+
showBackground = true,
12+
backgroundColor = "#52525B",
13+
backgroundOpacity = 1,
14+
backgroundMetalness = 0,
15+
backgroundRoughness = 1,
16+
}: {
17+
url: string;
18+
isUnlocked: boolean;
19+
Disc: DiscSpec;
20+
showBackground?: boolean;
21+
backgroundColor?: THREE.ColorRepresentation;
22+
backgroundOpacity?: number;
23+
backgroundMetalness?: number;
24+
backgroundRoughness?: number
25+
}) {
26+
const texture = useTexture(url);
27+
texture.colorSpace = THREE.SRGBColorSpace;
28+
texture.anisotropy = 2;
29+
30+
return (
31+
<group>
32+
{showBackground && (
33+
<mesh renderOrder={1} position={[0, 0, 0]}>
34+
<circleGeometry args={[Disc.radius, Disc.segments]} />
35+
<meshStandardMaterial
36+
color={backgroundColor}
37+
opacity={backgroundOpacity}
38+
transparent={backgroundOpacity < 1}
39+
metalness={backgroundMetalness}
40+
roughness={backgroundRoughness}
41+
polygonOffset
42+
polygonOffsetFactor={1}
43+
polygonOffsetUnits={1}
44+
depthWrite={true}
45+
depthTest={true}
46+
side={THREE.FrontSide}
47+
/>
48+
</mesh>
49+
)}
50+
51+
<mesh renderOrder={2} position={[0, 0, 0.01]}>
52+
<circleGeometry args={[Disc.radius, Disc.segments]} />
53+
<meshBasicMaterial
54+
colorWrite={false}
55+
depthWrite={true}
56+
depthTest={true}
57+
transparent={false}
58+
side={THREE.FrontSide}
59+
/>
60+
</mesh>
61+
62+
<mesh position={[0, 0, 0.0101]} renderOrder={3}>
1363
<circleGeometry args={[Disc.radius, Disc.segments]} />
1464
<meshPhysicalMaterial
1565
map={texture}
66+
transparent={true}
1667
roughness={0.65}
1768
metalness={0.0}
1869
clearcoat={0.05}
1970
clearcoatRoughness={0.6}
20-
transparent={false}
2171
color={isUnlocked ? 0xffffff : 0x808080}
72+
alphaTest={0.05}
73+
depthWrite={false}
74+
depthTest={true}
75+
side={THREE.FrontSide}
2276
toneMapped
77+
2378
/>
2479
</mesh>
25-
);
26-
}
27-
80+
</group>
81+
);
82+
}

components/profile/reward-board/component/requirement-panel.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Card, CardContent } from "@/components/ui/card";
1+
import { Card, CardContent, CardTitle } from "@/components/ui/card";
22
import { Separator } from "@/components/ui/separator";
33
import { Check } from "lucide-react";
44

@@ -11,8 +11,10 @@ type Requirement = {
1111

1212
export function RequirementsPanel({
1313
requirements = [],
14+
title
1415
}: {
1516
requirements?: Requirement[];
17+
title?: string;
1618
}) {
1719
const total = requirements.reduce(
1820
(acc, r) => acc + Number(r.points ?? 0),
@@ -22,9 +24,15 @@ export function RequirementsPanel({
2224
return (
2325
<div >
2426
<Card className="h-full dark:bg-zinc-600 shadow-none ">
27+
28+
2529
<CardContent className="p-0 h-full flex flex-col">
30+
<CardTitle className="text-center text-lg font-semibold dark:text-white text-gray-900 ">
31+
{title}
32+
</CardTitle>
33+
2634
<div className="px-6 pt-6 pb-2">
27-
<h3 className="text-base text-center font-semibold dark:text-white text-gray-900 mb-4">
35+
<h3 className="text-base font-semibold dark:text-white text-gray-900 ">
2836
Requirements
2937
</h3>
3038
</div>

components/profile/reward-board/component/reward-board.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export default async function RewardBoard() {
6262
requirements={reward.requirements}
6363
id={reward.id}
6464
is_unlocked={reward.is_unlocked}
65-
65+
6666
/>
6767
));
6868

@@ -92,7 +92,7 @@ export default async function RewardBoard() {
9292
</div>
9393
</div>
9494
) : (
95-
<div className="grid gap-4 sm:gap-6 lg:gap-8 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5">
95+
<div className="grid gap grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5">
9696
{rewards}
9797
</div>
9898
)}
@@ -111,7 +111,7 @@ export default async function RewardBoard() {
111111
</div>
112112
</div>
113113
) : (
114-
<div className="grid gap-4 sm:gap-6 lg:gap-8 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5">
114+
<div className="grid gap-y-4 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5">
115115
{academyRewards}
116116
</div>
117117
)}

components/profile/reward-board/component/reward-card.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
99
import { StaticMedal } from "./static-metal";
1010
import { AutoRotateMedal } from "./auto-rotate-badge";
1111

12-
const DISC = { radius: 0.92, segments: 90 };
12+
const DISC = { radius: 1.3, segments: 200 };
1313

1414
export const RewardCard = ({
1515
name,
@@ -24,27 +24,29 @@ export const RewardCard = ({
2424
return (
2525
<>
2626
<div
27-
className={`w-full max-w-sm mx-auto ${className ?? ""}`}
27+
className={` ${className ?? ""}`}
2828
style={{ userSelect: "none" }}
2929
>
3030
<div
31-
style={{ width: "100%", height: 300, cursor: "pointer" }}
31+
32+
className=" h-[230px] cursor-pointer"
3233
onClick={() => setOpen(true)}
3334
>
3435
<Canvas
36+
3537
shadows={false}
3638
dpr={[1, 2]}
3739
camera={{ position: [0, 0, 4.1], fov: 45 }}
3840
frameloop="demand"
3941
gl={{
40-
antialias: false,
42+
antialias: true,
4143
alpha: true,
4244
outputColorSpace: THREE.SRGBColorSpace,
4345
toneMapping: THREE.ACESFilmicToneMapping,
4446
toneMappingExposure: 0.8,
4547

4648
}}
47-
style={{ background: "transparent" }}
49+
4850
>
4951
<ambientLight intensity={1} />
5052
<directionalLight position={[2.2, 3, 5]} intensity={1.15} />
@@ -60,13 +62,14 @@ export const RewardCard = ({
6062
</VisuallyHidden>
6163
<DialogContent
6264
hideCloseButton={true}
63-
onOpenAutoFocus={(e) => e.preventDefault()}
64-
onCloseAutoFocus={(e) => e.preventDefault()}
65-
className="max-w-lg w-[360px] bg-transparent shadow-none border-none p-0 flex flex-col items-center gap-6"
65+
onOpenAutoFocus={(e) => e.preventDefault()}
66+
onCloseAutoFocus={(e) => e.preventDefault()}
67+
className="max-w-lg bg-transparent shadow-none border-none p-0 flex flex-col items-center"
6668
style={{ filter: "none", WebkitFilter: "none" }}
6769
>
68-
<div style={{ width: "100%", height: 360 }}>
70+
<div style={{ width: "100%", height: 250 }}>
6971
<Canvas
72+
className="block align-top"
7073
dpr={[1, 2]}
7174
camera={{ position: [0, 0, 4.3], fov: 45 }}
7275
gl={{
@@ -94,7 +97,7 @@ export const RewardCard = ({
9497

9598
{requirements && requirements.length > 0 && (
9699
<div >
97-
<RequirementsPanel requirements={requirements as any} />
100+
<RequirementsPanel requirements={requirements as any} title={name} />
98101
</div>
99102
)}
100103
</DialogContent>

0 commit comments

Comments
 (0)