upgrade to tamagui v2 and guest pwa overhaul
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { Camera, UploadCloud, Sparkles, Zap } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
export default function Mockup01CaptureOrbit() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Mockup 01 - Capture Orbit"
|
||||
subtitle="Full-screen capture hub with orbiting actions"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'radial-gradient(circle at 50% 10%, rgba(248, 113, 113, 0.18), transparent 55%)',
|
||||
}}
|
||||
>
|
||||
<MockupCard padding="$3">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack gap="$1">
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Event energy
|
||||
</Text>
|
||||
<MockupLabel>87 moments today</MockupLabel>
|
||||
</YStack>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Zap size={16} color="#F97316" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Live
|
||||
</Text>
|
||||
</XStack>
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
|
||||
<YStack alignItems="center" gap="$4">
|
||||
<YStack
|
||||
width={260}
|
||||
height={260}
|
||||
borderRadius={130}
|
||||
backgroundColor="$surface"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
gap="$2"
|
||||
style={{ boxShadow: '0 12px 40px rgba(15, 23, 42, 0.08)' }}
|
||||
>
|
||||
<Camera size={32} color="#0F172A" />
|
||||
<Text fontSize="$5" fontWeight="$8" fontFamily="$display">
|
||||
Tap to capture
|
||||
</Text>
|
||||
<Button size="$4" backgroundColor="$primary" borderRadius="$pill">
|
||||
Capture
|
||||
</Button>
|
||||
</YStack>
|
||||
|
||||
<XStack gap="$3">
|
||||
{[
|
||||
{ icon: <UploadCloud size={20} color="#0F172A" />, label: 'Upload' },
|
||||
{ icon: <Sparkles size={20} color="#0F172A" />, label: 'Prompt' },
|
||||
{ icon: <Camera size={20} color="#0F172A" />, label: 'Burst' },
|
||||
].map((item) => (
|
||||
<YStack
|
||||
key={item.label}
|
||||
width={72}
|
||||
height={72}
|
||||
borderRadius={36}
|
||||
backgroundColor="$surface"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
gap="$1"
|
||||
>
|
||||
{item.icon}
|
||||
<Text fontSize="$2" fontWeight="$6">
|
||||
{item.label}
|
||||
</Text>
|
||||
</YStack>
|
||||
))}
|
||||
</XStack>
|
||||
</YStack>
|
||||
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack gap="$1">
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Upload queue
|
||||
</Text>
|
||||
<MockupLabel>3 queued, 1 sending</MockupLabel>
|
||||
</YStack>
|
||||
<Button size="$3" backgroundColor="$surface" borderRadius="$pill" borderWidth={1} borderColor="$borderColor">
|
||||
View
|
||||
</Button>
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Filter, Image as ImageIcon } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupChip, MockupLabel, MockupTile } from './MockupPrimitives';
|
||||
|
||||
export default function Mockup02GalleryMosaic() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Mockup 02 - Gallery Mosaic"
|
||||
subtitle="Image-first grid with fast filters"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'linear-gradient(160deg, rgba(248, 250, 252, 0.9), rgba(255, 245, 240, 0.9))',
|
||||
}}
|
||||
>
|
||||
<MockupCard padding="$3">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<ImageIcon size={18} color="#0F172A" />
|
||||
<Text fontSize="$4" fontWeight="$8">
|
||||
Gallery
|
||||
</Text>
|
||||
</XStack>
|
||||
<Filter size={18} color="#0F172A" />
|
||||
</XStack>
|
||||
<XStack gap="$2" flexWrap="wrap">
|
||||
{['All', 'Friends', 'Dancefloor', 'Candid'].map((chip) => (
|
||||
<MockupChip key={chip}>
|
||||
<Text fontSize="$2" fontWeight="$6">
|
||||
{chip}
|
||||
</Text>
|
||||
</MockupChip>
|
||||
))}
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
|
||||
<XStack gap="$3">
|
||||
<YStack flex={1} gap="$3">
|
||||
<MockupTile height={160}>
|
||||
<MockupLabel>Hero moment</MockupLabel>
|
||||
</MockupTile>
|
||||
<XStack gap="$3">
|
||||
<MockupTile flex={1} height={90} />
|
||||
<MockupTile flex={1} height={90} />
|
||||
</XStack>
|
||||
<MockupTile height={120} />
|
||||
</YStack>
|
||||
<YStack flex={1} gap="$3">
|
||||
<XStack gap="$3">
|
||||
<MockupTile flex={1} height={110} />
|
||||
<MockupTile flex={1} height={110} />
|
||||
</XStack>
|
||||
<MockupTile height={180}>
|
||||
<MockupLabel>Live spotlight</MockupLabel>
|
||||
</MockupTile>
|
||||
<MockupTile height={90} />
|
||||
</YStack>
|
||||
</XStack>
|
||||
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack gap="$1">
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Newest uploads
|
||||
</Text>
|
||||
<MockupLabel>Refreshes every 10s</MockupLabel>
|
||||
</YStack>
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
22 new
|
||||
</Text>
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { Sparkles, Trophy, Play } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
export default function Mockup03PromptQuest() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Mockup 03 - Prompt Quest"
|
||||
subtitle="Prompt hero with progress and task ladder"
|
||||
>
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Sparkles size={18} color="#F43F5E" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Prompt of the hour
|
||||
</Text>
|
||||
</XStack>
|
||||
<Text fontSize="$7" fontFamily="$display" fontWeight="$8">
|
||||
Capture the boldest dance move
|
||||
</Text>
|
||||
<MockupLabel>Earn 120 points for completing this prompt.</MockupLabel>
|
||||
<YStack gap="$2">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
Quest progress
|
||||
</Text>
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
65%
|
||||
</Text>
|
||||
</XStack>
|
||||
<YStack backgroundColor="$muted" borderRadius="$pill" height={10} overflow="hidden">
|
||||
<YStack backgroundColor="$primary" width="65%" height={10} />
|
||||
</YStack>
|
||||
</YStack>
|
||||
<Button size="$4" backgroundColor="$primary" borderRadius="$pill">
|
||||
Start capture
|
||||
</Button>
|
||||
</MockupCard>
|
||||
|
||||
<YStack gap="$3">
|
||||
{[1, 2, 3].map((item) => (
|
||||
<MockupCard key={item} padding="$3">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack gap="$1">
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Task {item}
|
||||
</Text>
|
||||
<MockupLabel>Quick challenge to spark the moment.</MockupLabel>
|
||||
</YStack>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Trophy size={16} color="#F59E0B" />
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
+50
|
||||
</Text>
|
||||
</XStack>
|
||||
</XStack>
|
||||
<Button size="$3" backgroundColor="$surface" borderRadius="$pill" borderWidth={1} borderColor="$borderColor">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Play size={14} color="#0F172A" />
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
Play task
|
||||
</Text>
|
||||
</XStack>
|
||||
</Button>
|
||||
</MockupCard>
|
||||
))}
|
||||
</YStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Clock, Image as ImageIcon } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
const timeline = [
|
||||
{ time: '18:40', title: 'Sparkler exit', caption: '12 new uploads' },
|
||||
{ time: '18:22', title: 'First dance', caption: '7 moments added' },
|
||||
{ time: '18:10', title: 'Toast round', caption: '5 guest favorites' },
|
||||
{ time: '17:55', title: 'Arrival glow', caption: '4 candid shots' },
|
||||
];
|
||||
|
||||
export default function Mockup04TimelineStream() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Mockup 04 - Timeline Stream"
|
||||
subtitle="Chronological feed with time markers"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'linear-gradient(180deg, rgba(254, 252, 232, 0.9), rgba(255, 255, 255, 0.95))',
|
||||
}}
|
||||
>
|
||||
<MockupCard padding="$3">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Clock size={16} color="#0F172A" />
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Live timeline
|
||||
</Text>
|
||||
</XStack>
|
||||
<MockupLabel>Moments grouped by when they happened.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<YStack gap="$3">
|
||||
{timeline.map((item, index) => (
|
||||
<XStack key={item.time} gap="$3" alignItems="flex-start">
|
||||
<YStack alignItems="center" gap="$2" width={60}>
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
{item.time}
|
||||
</Text>
|
||||
<YStack width={2} flex={1} backgroundColor="$borderColor" opacity={index === timeline.length - 1 ? 0 : 1} />
|
||||
</YStack>
|
||||
<MockupCard flex={1} padding="$3">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<ImageIcon size={16} color="#0F172A" />
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
{item.title}
|
||||
</Text>
|
||||
</XStack>
|
||||
<MockupLabel>{item.caption}</MockupLabel>
|
||||
<XStack gap="$2">
|
||||
{[1, 2, 3].map((tile) => (
|
||||
<YStack
|
||||
key={tile}
|
||||
flex={1}
|
||||
height={56}
|
||||
borderRadius="$tile"
|
||||
backgroundColor="$muted"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
/>
|
||||
))}
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
</XStack>
|
||||
))}
|
||||
</YStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
81
resources/js/guest-v2/screens/mockups/Mockup05CompassHub.tsx
Normal file
81
resources/js/guest-v2/screens/mockups/Mockup05CompassHub.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Compass, Image as ImageIcon, Sparkles, UploadCloud } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
export default function Mockup05CompassHub() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Mockup 05 - Compass Hub"
|
||||
subtitle="Quadrant navigation around a central action"
|
||||
>
|
||||
<YStack position="relative" height={360} gap="$3">
|
||||
<XStack gap="$3">
|
||||
<MockupCard flex={1} height={150} justifyContent="center" alignItems="center">
|
||||
<ImageIcon size={20} color="#0F172A" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Gallery
|
||||
</Text>
|
||||
<MockupLabel>Browse moments</MockupLabel>
|
||||
</MockupCard>
|
||||
<MockupCard flex={1} height={150} justifyContent="center" alignItems="center">
|
||||
<UploadCloud size={20} color="#0F172A" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Upload
|
||||
</Text>
|
||||
<MockupLabel>Quick add</MockupLabel>
|
||||
</MockupCard>
|
||||
</XStack>
|
||||
<XStack gap="$3">
|
||||
<MockupCard flex={1} height={150} justifyContent="center" alignItems="center">
|
||||
<Sparkles size={20} color="#0F172A" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Tasks
|
||||
</Text>
|
||||
<MockupLabel>Earn points</MockupLabel>
|
||||
</MockupCard>
|
||||
<MockupCard flex={1} height={150} justifyContent="center" alignItems="center">
|
||||
<Compass size={20} color="#0F172A" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Live show
|
||||
</Text>
|
||||
<MockupLabel>See highlights</MockupLabel>
|
||||
</MockupCard>
|
||||
</XStack>
|
||||
|
||||
<YStack
|
||||
position="absolute"
|
||||
top="50%"
|
||||
left="50%"
|
||||
width={110}
|
||||
height={110}
|
||||
borderRadius={55}
|
||||
backgroundColor="$primary"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
style={{ transform: 'translate(-50%, -50%)' }}
|
||||
>
|
||||
<Text fontSize="$4" fontWeight="$8" color="white">
|
||||
Capture
|
||||
</Text>
|
||||
</YStack>
|
||||
</YStack>
|
||||
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack gap="$1">
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Event compass
|
||||
</Text>
|
||||
<MockupLabel>Tap any quadrant to jump.</MockupLabel>
|
||||
</YStack>
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
4 zones
|
||||
</Text>
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Camera, Grid2x2, Zap, UploadCloud } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel, MockupTile } from './MockupPrimitives';
|
||||
|
||||
export default function Mockup06SplitCapture() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Mockup 06 - Split Capture"
|
||||
subtitle="Camera preview plus quick tools and queue"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'linear-gradient(180deg, rgba(240, 249, 255, 0.95), rgba(255, 255, 255, 0.95))',
|
||||
}}
|
||||
>
|
||||
<YStack gap="$3">
|
||||
<YStack
|
||||
height={260}
|
||||
borderRadius="$card"
|
||||
backgroundColor="$muted"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
gap="$2"
|
||||
>
|
||||
<Camera size={32} color="#0F172A" />
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Live preview
|
||||
</Text>
|
||||
<MockupLabel>Tap anywhere to focus.</MockupLabel>
|
||||
</YStack>
|
||||
|
||||
<XStack gap="$3">
|
||||
{[
|
||||
{ icon: <Grid2x2 size={18} color="#0F172A" />, label: 'Grid' },
|
||||
{ icon: <Zap size={18} color="#F97316" />, label: 'Flash' },
|
||||
{ icon: <UploadCloud size={18} color="#0F172A" />, label: 'Upload' },
|
||||
].map((tool) => (
|
||||
<MockupCard key={tool.label} flex={1} padding="$3" alignItems="center">
|
||||
{tool.icon}
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
{tool.label}
|
||||
</Text>
|
||||
</MockupCard>
|
||||
))}
|
||||
</XStack>
|
||||
</YStack>
|
||||
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Upload queue
|
||||
</Text>
|
||||
<MockupLabel>2 waiting</MockupLabel>
|
||||
</XStack>
|
||||
<XStack gap="$2">
|
||||
{[1, 2, 3].map((tile) => (
|
||||
<MockupTile key={tile} flex={1} height={72} />
|
||||
))}
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
94
resources/js/guest-v2/screens/mockups/Mockup07SwipeDeck.tsx
Normal file
94
resources/js/guest-v2/screens/mockups/Mockup07SwipeDeck.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Heart, X, Send } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
export default function Mockup07SwipeDeck() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Mockup 07 - Swipe Deck"
|
||||
subtitle="Stacked cards for rapid review"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'radial-gradient(circle at 80% 0%, rgba(190, 24, 93, 0.12), transparent 50%)',
|
||||
}}
|
||||
>
|
||||
<MockupCard padding="$3">
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Review queue
|
||||
</Text>
|
||||
<MockupLabel>Swipe to approve or skip highlights.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<YStack height={360} position="relative">
|
||||
<MockupCard
|
||||
height={320}
|
||||
position="absolute"
|
||||
left={0}
|
||||
right={0}
|
||||
style={{ transform: 'translateY(24px) rotate(-2deg)' }}
|
||||
>
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Guest capture 3
|
||||
</Text>
|
||||
</MockupCard>
|
||||
<MockupCard
|
||||
height={330}
|
||||
position="absolute"
|
||||
left={0}
|
||||
right={0}
|
||||
style={{ transform: 'translateY(12px) rotate(1deg)' }}
|
||||
>
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Guest capture 2
|
||||
</Text>
|
||||
</MockupCard>
|
||||
<MockupCard height={340} position="absolute" left={0} right={0}>
|
||||
<Text fontSize="$6" fontFamily="$display" fontWeight="$8">
|
||||
Guest capture 1
|
||||
</Text>
|
||||
<MockupLabel>Tap for full view</MockupLabel>
|
||||
<YStack flex={1} borderRadius="$card" backgroundColor="$muted" />
|
||||
</MockupCard>
|
||||
</YStack>
|
||||
|
||||
<XStack gap="$3" justifyContent="center">
|
||||
<YStack
|
||||
width={64}
|
||||
height={64}
|
||||
borderRadius={32}
|
||||
backgroundColor="$surface"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<X size={20} color="#EF4444" />
|
||||
</YStack>
|
||||
<YStack
|
||||
width={72}
|
||||
height={72}
|
||||
borderRadius={36}
|
||||
backgroundColor="$primary"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<Heart size={24} color="white" />
|
||||
</YStack>
|
||||
<YStack
|
||||
width={64}
|
||||
height={64}
|
||||
borderRadius={32}
|
||||
backgroundColor="$surface"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<Send size={20} color="#0F172A" />
|
||||
</YStack>
|
||||
</XStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
58
resources/js/guest-v2/screens/mockups/Mockup08Daybook.tsx
Normal file
58
resources/js/guest-v2/screens/mockups/Mockup08Daybook.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Sun, CloudSun, MoonStar } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel, MockupTile } from './MockupPrimitives';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
key: 'morning',
|
||||
title: 'Morning glow',
|
||||
icon: <Sun size={18} color="#F97316" />,
|
||||
},
|
||||
{
|
||||
key: 'afternoon',
|
||||
title: 'Afternoon energy',
|
||||
icon: <CloudSun size={18} color="#F59E0B" />,
|
||||
},
|
||||
{
|
||||
key: 'night',
|
||||
title: 'Night sparkle',
|
||||
icon: <MoonStar size={18} color="#6366F1" />,
|
||||
},
|
||||
];
|
||||
|
||||
export default function Mockup08Daybook() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Mockup 08 - Daybook"
|
||||
subtitle="Morning/afternoon/night memory sections"
|
||||
>
|
||||
<MockupCard>
|
||||
<Text fontSize="$5" fontFamily="$display" fontWeight="$8">
|
||||
Today in moments
|
||||
</Text>
|
||||
<MockupLabel>Group memories by vibe, not just time.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<YStack gap="$4">
|
||||
{sections.map((section) => (
|
||||
<YStack key={section.key} gap="$2">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
{section.icon}
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
{section.title}
|
||||
</Text>
|
||||
</XStack>
|
||||
<XStack gap="$2">
|
||||
{[1, 2, 3].map((tile) => (
|
||||
<MockupTile key={tile} flex={1} height={110} />
|
||||
))}
|
||||
</XStack>
|
||||
</YStack>
|
||||
))}
|
||||
</YStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { CheckCircle2, Circle, ListChecks } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel, MockupTile } from './MockupPrimitives';
|
||||
|
||||
const tasks = [
|
||||
{ id: 1, label: 'Capture the first toast', done: true },
|
||||
{ id: 2, label: 'Find the loudest laugh', done: false },
|
||||
{ id: 3, label: 'Snap a detail shot', done: false },
|
||||
{ id: 4, label: 'Find the dance duo', done: true },
|
||||
];
|
||||
|
||||
export default function Mockup09ChecklistFlow() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Mockup 09 - Checklist Flow"
|
||||
subtitle="Tasks checklist paired with gallery progress"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'linear-gradient(180deg, rgba(244, 244, 255, 0.8), rgba(255, 255, 255, 0.9))',
|
||||
}}
|
||||
>
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<ListChecks size={18} color="#0F172A" />
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Today’s checklist
|
||||
</Text>
|
||||
</XStack>
|
||||
<MockupLabel>Complete tasks to unlock more prompts.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<MockupCard>
|
||||
<YStack gap="$2">
|
||||
{tasks.map((task) => (
|
||||
<XStack key={task.id} alignItems="center" gap="$2">
|
||||
{task.done ? (
|
||||
<CheckCircle2 size={18} color="#22C55E" />
|
||||
) : (
|
||||
<Circle size={18} color="#94A3B8" />
|
||||
)}
|
||||
<Text fontSize="$3" fontWeight="$6">
|
||||
{task.label}
|
||||
</Text>
|
||||
</XStack>
|
||||
))}
|
||||
</YStack>
|
||||
</MockupCard>
|
||||
|
||||
<MockupCard>
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Progress gallery
|
||||
</Text>
|
||||
<XStack gap="$2">
|
||||
{[1, 2, 3, 4].map((tile) => (
|
||||
<MockupTile key={tile} flex={1} height={70} />
|
||||
))}
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Play, Star, Share2 } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel, MockupTile } from './MockupPrimitives';
|
||||
|
||||
export default function Mockup10SpotlightReel() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Mockup 10 - Spotlight Reel"
|
||||
subtitle="Live highlight reel with action strip"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'radial-gradient(circle at 20% 0%, rgba(251, 191, 36, 0.2), transparent 55%)',
|
||||
}}
|
||||
>
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack gap="$1">
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Spotlight reel
|
||||
</Text>
|
||||
<MockupLabel>Live highlights curated by guests.</MockupLabel>
|
||||
</YStack>
|
||||
<Play size={18} color="#0F172A" />
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
|
||||
<XStack gap="$2">
|
||||
{[1, 2, 3, 4, 5].map((tile) => (
|
||||
<MockupTile key={tile} flex={1} height={70} />
|
||||
))}
|
||||
</XStack>
|
||||
|
||||
<MockupCard>
|
||||
<Text fontSize="$6" fontFamily="$display" fontWeight="$8">
|
||||
Now showing
|
||||
</Text>
|
||||
<YStack height={200} borderRadius="$card" backgroundColor="$muted" />
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Star size={16} color="#F59E0B" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
4.8 rating
|
||||
</Text>
|
||||
</XStack>
|
||||
<Share2 size={16} color="#0F172A" />
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
|
||||
<XStack gap="$2">
|
||||
{['Like', 'Save', 'Share'].map((action) => (
|
||||
<MockupCard key={action} flex={1} padding="$3" alignItems="center">
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
{action}
|
||||
</Text>
|
||||
</MockupCard>
|
||||
))}
|
||||
</XStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
65
resources/js/guest-v2/screens/mockups/MockupFrame.tsx
Normal file
65
resources/js/guest-v2/screens/mockups/MockupFrame.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { XStack, YStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { ArrowLeft } from 'lucide-react';
|
||||
|
||||
type MockupFrameProps = {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
hideHeader?: boolean;
|
||||
backgroundStyle?: React.CSSProperties;
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export default function MockupFrame({
|
||||
title,
|
||||
subtitle,
|
||||
hideHeader,
|
||||
backgroundStyle,
|
||||
children,
|
||||
}: MockupFrameProps) {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<YStack
|
||||
minHeight="100vh"
|
||||
backgroundColor="$background"
|
||||
padding="$4"
|
||||
gap="$4"
|
||||
style={backgroundStyle}
|
||||
>
|
||||
{!hideHeader && (
|
||||
<XStack alignItems="center" justifyContent="space-between" gap="$3">
|
||||
<Button
|
||||
size="$3"
|
||||
backgroundColor="$surface"
|
||||
borderRadius="$pill"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
onPress={() => navigate('/mockups')}
|
||||
>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<ArrowLeft size={16} color="#0F172A" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Back
|
||||
</Text>
|
||||
</XStack>
|
||||
</Button>
|
||||
<YStack alignItems="flex-end" gap="$1">
|
||||
<Text fontSize="$5" fontWeight="$8" fontFamily="$display">
|
||||
{title}
|
||||
</Text>
|
||||
{subtitle ? (
|
||||
<Text fontSize="$2" color="$color" opacity={0.6}>
|
||||
{subtitle}
|
||||
</Text>
|
||||
) : null}
|
||||
</YStack>
|
||||
</XStack>
|
||||
)}
|
||||
{children}
|
||||
</YStack>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { Camera, Zap, Users } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
export default function MockupHome01PulseHero() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Home 01 - Pulse Hero"
|
||||
subtitle="Live stats + big capture call-to-action"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'radial-gradient(circle at 20% 0%, rgba(59, 130, 246, 0.16), transparent 50%)',
|
||||
}}
|
||||
>
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack gap="$1">
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Sofia + Luca
|
||||
</Text>
|
||||
<MockupLabel>Reception in progress</MockupLabel>
|
||||
</YStack>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Zap size={16} color="#F97316" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Live
|
||||
</Text>
|
||||
</XStack>
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
|
||||
<YStack
|
||||
padding="$5"
|
||||
borderRadius="$card"
|
||||
backgroundColor="$surface"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
alignItems="center"
|
||||
gap="$3"
|
||||
>
|
||||
<Camera size={28} color="#0F172A" />
|
||||
<Text fontSize="$7" fontFamily="$display" fontWeight="$8">
|
||||
Capture the next moment
|
||||
</Text>
|
||||
<MockupLabel>Share it instantly with the room.</MockupLabel>
|
||||
<Button size="$4" backgroundColor="$primary" borderRadius="$pill">
|
||||
Start capture
|
||||
</Button>
|
||||
</YStack>
|
||||
|
||||
<XStack gap="$3">
|
||||
<MockupCard flex={1} alignItems="center">
|
||||
<Text fontSize="$6" fontWeight="$8">
|
||||
128
|
||||
</Text>
|
||||
<MockupLabel>Photos today</MockupLabel>
|
||||
</MockupCard>
|
||||
<MockupCard flex={1} alignItems="center">
|
||||
<Users size={18} color="#0F172A" />
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
54 guests
|
||||
</Text>
|
||||
</MockupCard>
|
||||
</XStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Camera, Sparkles, Image as ImageIcon, Users } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
const rings = [
|
||||
{ label: 'Capture', icon: <Camera size={18} color="#0F172A" /> },
|
||||
{ label: 'Prompts', icon: <Sparkles size={18} color="#0F172A" /> },
|
||||
{ label: 'Gallery', icon: <ImageIcon size={18} color="#0F172A" /> },
|
||||
{ label: 'Guests', icon: <Users size={18} color="#0F172A" /> },
|
||||
];
|
||||
|
||||
export default function MockupHome02StoryRings() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Home 02 - Story Rings"
|
||||
subtitle="Circular quick actions with story chips"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'radial-gradient(circle at 80% 0%, rgba(244, 63, 94, 0.14), transparent 55%)',
|
||||
}}
|
||||
>
|
||||
<MockupCard>
|
||||
<Text fontSize="$5" fontFamily="$display" fontWeight="$8">
|
||||
Morning glow
|
||||
</Text>
|
||||
<MockupLabel>Tap a ring to jump in.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<XStack justifyContent="space-between">
|
||||
{rings.map((ring) => (
|
||||
<YStack key={ring.label} alignItems="center" gap="$2">
|
||||
<YStack
|
||||
width={72}
|
||||
height={72}
|
||||
borderRadius={36}
|
||||
backgroundColor="$surface"
|
||||
borderWidth={2}
|
||||
borderColor="$primary"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
{ring.icon}
|
||||
</YStack>
|
||||
<Text fontSize="$2" fontWeight="$6">
|
||||
{ring.label}
|
||||
</Text>
|
||||
</YStack>
|
||||
))}
|
||||
</XStack>
|
||||
|
||||
<YStack gap="$3">
|
||||
<MockupCard>
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Story highlights
|
||||
</Text>
|
||||
<XStack gap="$2">
|
||||
{[1, 2, 3].map((chip) => (
|
||||
<YStack
|
||||
key={chip}
|
||||
flex={1}
|
||||
height={90}
|
||||
borderRadius="$tile"
|
||||
backgroundColor="$muted"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
/>
|
||||
))}
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
</YStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Play, Share2, Cast } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel, MockupTile } from './MockupPrimitives';
|
||||
|
||||
export default function MockupHome03LiveStream() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Home 03 - Live Stream"
|
||||
subtitle="Highlight reel + action strip"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'linear-gradient(180deg, rgba(254, 242, 242, 0.9), rgba(255, 255, 255, 0.95))',
|
||||
}}
|
||||
>
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Cast size={18} color="#0F172A" />
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Live highlight stream
|
||||
</Text>
|
||||
</XStack>
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
24 now
|
||||
</Text>
|
||||
</XStack>
|
||||
<MockupLabel>Tap to join the live wall.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<MockupCard>
|
||||
<YStack height={210} borderRadius="$card" backgroundColor="$muted" />
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Play size={16} color="#0F172A" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Now playing
|
||||
</Text>
|
||||
</XStack>
|
||||
<Share2 size={16} color="#0F172A" />
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
|
||||
<XStack gap="$2">
|
||||
{[1, 2, 3, 4].map((tile) => (
|
||||
<MockupTile key={tile} flex={1} height={70} />
|
||||
))}
|
||||
</XStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { Sparkles, Trophy } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
export default function MockupHome04TaskSprint() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Home 04 - Task Sprint"
|
||||
subtitle="Prompt ladder + progress meter"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'radial-gradient(circle at 20% 0%, rgba(167, 139, 250, 0.2), transparent 55%)',
|
||||
}}
|
||||
>
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Sparkles size={18} color="#8B5CF6" />
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Sprint of the hour
|
||||
</Text>
|
||||
</XStack>
|
||||
<Text fontSize="$6" fontFamily="$display" fontWeight="$8">
|
||||
Capture three smiles in 5 minutes
|
||||
</Text>
|
||||
<MockupLabel>Earn double points for finishing early.</MockupLabel>
|
||||
<YStack gap="$2">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
Progress
|
||||
</Text>
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
2/3
|
||||
</Text>
|
||||
</XStack>
|
||||
<YStack backgroundColor="$muted" borderRadius="$pill" height={10} overflow="hidden">
|
||||
<YStack backgroundColor="$primary" width="66%" height={10} />
|
||||
</YStack>
|
||||
</YStack>
|
||||
<Button size="$4" backgroundColor="$primary" borderRadius="$pill">
|
||||
Continue sprint
|
||||
</Button>
|
||||
</MockupCard>
|
||||
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Rewards
|
||||
</Text>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Trophy size={16} color="#F59E0B" />
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
+180
|
||||
</Text>
|
||||
</XStack>
|
||||
</XStack>
|
||||
<MockupLabel>Unlock more prompts after this sprint.</MockupLabel>
|
||||
</MockupCard>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Image as ImageIcon, Filter } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel, MockupTile } from './MockupPrimitives';
|
||||
|
||||
export default function MockupHome05GalleryFirst() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Home 05 - Gallery First"
|
||||
subtitle="Grid preview + quick filters"
|
||||
>
|
||||
<MockupCard padding="$3">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<ImageIcon size={18} color="#0F172A" />
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Moments
|
||||
</Text>
|
||||
</XStack>
|
||||
<Filter size={16} color="#0F172A" />
|
||||
</XStack>
|
||||
<MockupLabel>Start browsing before you upload.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<XStack gap="$2">
|
||||
{[1, 2, 3].map((tile) => (
|
||||
<MockupTile key={tile} flex={1} height={100} />
|
||||
))}
|
||||
</XStack>
|
||||
<XStack gap="$2">
|
||||
{[4, 5, 6].map((tile) => (
|
||||
<MockupTile key={tile} flex={1} height={120} />
|
||||
))}
|
||||
</XStack>
|
||||
|
||||
<MockupCard>
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Latest uploads
|
||||
</Text>
|
||||
<MockupLabel>Updated every 15 seconds.</MockupLabel>
|
||||
</MockupCard>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { Camera, CheckCircle2 } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
export default function MockupHome06CalmFocus() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Home 06 - Calm Focus"
|
||||
subtitle="Minimal home with one primary action"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'linear-gradient(180deg, rgba(236, 254, 255, 0.9), rgba(255, 255, 255, 0.95))',
|
||||
}}
|
||||
>
|
||||
<YStack
|
||||
padding="$5"
|
||||
borderRadius="$card"
|
||||
backgroundColor="$surface"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
gap="$3"
|
||||
>
|
||||
<Text fontSize="$6" fontFamily="$display" fontWeight="$8">
|
||||
Capture something quiet
|
||||
</Text>
|
||||
<MockupLabel>One great photo beats five ok ones.</MockupLabel>
|
||||
<Button size="$4" backgroundColor="$primary" borderRadius="$pill">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Camera size={18} color="white" />
|
||||
<Text fontSize="$3" color="white">
|
||||
Open camera
|
||||
</Text>
|
||||
</XStack>
|
||||
</Button>
|
||||
</YStack>
|
||||
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Uploads today
|
||||
</Text>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<CheckCircle2 size={16} color="#22C55E" />
|
||||
<Text fontSize="$2" fontWeight="$7">
|
||||
12 approved
|
||||
</Text>
|
||||
</XStack>
|
||||
</XStack>
|
||||
<MockupLabel>Everything is synced and safe.</MockupLabel>
|
||||
</MockupCard>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Camera, ArrowUpRight } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
export default function MockupHome07MomentStack() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Home 07 - Moment Stack"
|
||||
subtitle="Stacked cards for rapid capture"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'radial-gradient(circle at 70% 0%, rgba(14, 165, 233, 0.15), transparent 50%)',
|
||||
}}
|
||||
>
|
||||
<MockupCard>
|
||||
<Text fontSize="$5" fontFamily="$display" fontWeight="$8">
|
||||
Moment stack
|
||||
</Text>
|
||||
<MockupLabel>Start at the top and keep capturing.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<YStack height={320} position="relative">
|
||||
<MockupCard
|
||||
height={220}
|
||||
position="absolute"
|
||||
left={0}
|
||||
right={0}
|
||||
style={{ transform: 'translateY(28px) rotate(-2deg)' }}
|
||||
>
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Prompt: hands in the air
|
||||
</Text>
|
||||
</MockupCard>
|
||||
<MockupCard
|
||||
height={230}
|
||||
position="absolute"
|
||||
left={0}
|
||||
right={0}
|
||||
style={{ transform: 'translateY(14px) rotate(1deg)' }}
|
||||
>
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Prompt: candid laugh
|
||||
</Text>
|
||||
</MockupCard>
|
||||
<MockupCard height={240} position="absolute" left={0} right={0}>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$5" fontWeight="$8">
|
||||
Prompt: dance floor
|
||||
</Text>
|
||||
<ArrowUpRight size={18} color="#0F172A" />
|
||||
</XStack>
|
||||
<MockupLabel>Tap to start this capture.</MockupLabel>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Camera size={18} color="#0F172A" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Open camera
|
||||
</Text>
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
</YStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { Clock, Play } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
export default function MockupHome08CountdownStage() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Home 08 - Countdown Stage"
|
||||
subtitle="Event timing + live show entry"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'linear-gradient(180deg, rgba(254, 249, 195, 0.9), rgba(255, 255, 255, 0.95))',
|
||||
}}
|
||||
>
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Clock size={16} color="#0F172A" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Next highlight in
|
||||
</Text>
|
||||
</XStack>
|
||||
<Text fontSize="$7" fontFamily="$display" fontWeight="$8">
|
||||
04:32
|
||||
</Text>
|
||||
<MockupLabel>Stay ready for the next big moment.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<YStack
|
||||
padding="$4"
|
||||
borderRadius="$card"
|
||||
backgroundColor="$surface"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
gap="$3"
|
||||
>
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Live show stage
|
||||
</Text>
|
||||
<MockupLabel>Jump into the projected highlight wall.</MockupLabel>
|
||||
<Button size="$4" backgroundColor="$primary" borderRadius="$pill">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Play size={16} color="white" />
|
||||
<Text fontSize="$3" color="white">
|
||||
Open live show
|
||||
</Text>
|
||||
</XStack>
|
||||
</Button>
|
||||
</YStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { Share2, QrCode, Link } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
export default function MockupHome09ShareHub() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Home 09 - Share Hub"
|
||||
subtitle="Invite + QR + guest sharing tools"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'radial-gradient(circle at 25% 0%, rgba(14, 165, 233, 0.18), transparent 50%)',
|
||||
}}
|
||||
>
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Share2 size={18} color="#0F172A" />
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Invite guests
|
||||
</Text>
|
||||
</XStack>
|
||||
<MockupLabel>Share the link or show the QR code.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<XStack gap="$3">
|
||||
<MockupCard flex={1} alignItems="center" gap="$2">
|
||||
<QrCode size={24} color="#0F172A" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Show QR
|
||||
</Text>
|
||||
<MockupLabel>Scan to join</MockupLabel>
|
||||
</MockupCard>
|
||||
<MockupCard flex={1} alignItems="center" gap="$2">
|
||||
<Link size={24} color="#0F172A" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Copy link
|
||||
</Text>
|
||||
<MockupLabel>Send in chat</MockupLabel>
|
||||
</MockupCard>
|
||||
</XStack>
|
||||
|
||||
<YStack
|
||||
padding="$4"
|
||||
borderRadius="$card"
|
||||
backgroundColor="$surface"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
gap="$3"
|
||||
>
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Welcome pack
|
||||
</Text>
|
||||
<MockupLabel>Tips for guests and upload etiquette.</MockupLabel>
|
||||
<Button size="$3" backgroundColor="$primary" borderRadius="$pill" alignSelf="flex-start">
|
||||
Open guide
|
||||
</Button>
|
||||
</YStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Palette, Sparkles } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel, MockupTile } from './MockupPrimitives';
|
||||
|
||||
const palettes = ['#FDE68A', '#F9A8D4', '#A5B4FC', '#6EE7B7', '#FCA5A5'];
|
||||
|
||||
export default function MockupHome10Moodboard() {
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Home 10 - Moodboard"
|
||||
subtitle="Palette + prompts to set the vibe"
|
||||
backgroundStyle={{
|
||||
backgroundImage: 'linear-gradient(180deg, rgba(255, 247, 237, 0.95), rgba(255, 255, 255, 0.95))',
|
||||
}}
|
||||
>
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Palette size={18} color="#0F172A" />
|
||||
<Text fontSize="$4" fontWeight="$7">
|
||||
Moodboard
|
||||
</Text>
|
||||
</XStack>
|
||||
<MockupLabel>Pick a vibe for the next wave of shots.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<XStack gap="$2">
|
||||
{palettes.map((color) => (
|
||||
<YStack
|
||||
key={color}
|
||||
flex={1}
|
||||
height={54}
|
||||
borderRadius="$pill"
|
||||
style={{ backgroundColor: color }}
|
||||
/>
|
||||
))}
|
||||
</XStack>
|
||||
|
||||
<MockupCard>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Sparkles size={16} color="#F43F5E" />
|
||||
<Text fontSize="$3" fontWeight="$7">
|
||||
Prompt ideas
|
||||
</Text>
|
||||
</XStack>
|
||||
<XStack gap="$2">
|
||||
{[1, 2, 3].map((tile) => (
|
||||
<MockupTile key={tile} flex={1} height={80} />
|
||||
))}
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
65
resources/js/guest-v2/screens/mockups/MockupPrimitives.tsx
Normal file
65
resources/js/guest-v2/screens/mockups/MockupPrimitives.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import React from 'react';
|
||||
import { XStack, YStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
|
||||
type StackProps = React.ComponentProps<typeof YStack>;
|
||||
|
||||
type RowProps = React.ComponentProps<typeof XStack>;
|
||||
|
||||
export function MockupCard({ children, ...props }: StackProps) {
|
||||
return (
|
||||
<YStack
|
||||
padding="$4"
|
||||
borderRadius="$card"
|
||||
backgroundColor="$surface"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
gap="$3"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</YStack>
|
||||
);
|
||||
}
|
||||
|
||||
export function MockupTile({ children, ...props }: StackProps) {
|
||||
return (
|
||||
<YStack
|
||||
padding="$3"
|
||||
borderRadius="$tile"
|
||||
backgroundColor="$muted"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
gap="$2"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</YStack>
|
||||
);
|
||||
}
|
||||
|
||||
export function MockupChip({ children, ...props }: RowProps) {
|
||||
return (
|
||||
<XStack
|
||||
alignItems="center"
|
||||
gap="$2"
|
||||
paddingVertical="$2"
|
||||
paddingHorizontal="$3"
|
||||
borderRadius="$pill"
|
||||
backgroundColor="$surface"
|
||||
borderWidth={1}
|
||||
borderColor="$borderColor"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</XStack>
|
||||
);
|
||||
}
|
||||
|
||||
export function MockupLabel({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<Text fontSize="$2" color="$color" opacity={0.6}>
|
||||
{children}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { ArrowRight, Home } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
const mockups = [
|
||||
{ id: '1', title: 'Pulse Hero', description: 'Live stats + big capture call-to-action.' },
|
||||
{ id: '2', title: 'Story Rings', description: 'Circular quick actions with story chips.' },
|
||||
{ id: '3', title: 'Live Stream', description: 'Highlight reel + action strip.' },
|
||||
{ id: '4', title: 'Task Sprint', description: 'Prompt ladder + progress meter.' },
|
||||
{ id: '5', title: 'Gallery First', description: 'Grid preview + quick filters.' },
|
||||
{ id: '6', title: 'Calm Focus', description: 'Minimal home with one primary action.' },
|
||||
{ id: '7', title: 'Moment Stack', description: 'Stacked cards for rapid capture.' },
|
||||
{ id: '8', title: 'Countdown Stage', description: 'Event timing + live show entry.' },
|
||||
{ id: '9', title: 'Share Hub', description: 'Invite + QR + guest sharing tools.' },
|
||||
{ id: '10', title: 'Moodboard', description: 'Palette + prompts to set the vibe.' },
|
||||
];
|
||||
|
||||
export default function MockupsHomeIndexScreen() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Home concepts"
|
||||
subtitle="10 start screen ideas for the new guest PWA"
|
||||
>
|
||||
<MockupCard padding="$3">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Home size={18} color="#0F172A" />
|
||||
<Text fontSize="$4" fontWeight="$8">
|
||||
Start screen concepts
|
||||
</Text>
|
||||
</XStack>
|
||||
<MockupLabel>Pick one as the north star for v2.</MockupLabel>
|
||||
</MockupCard>
|
||||
|
||||
<YStack gap="$3">
|
||||
{mockups.map((mockup) => (
|
||||
<MockupCard key={mockup.id} gap="$2">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$5" fontWeight="$8" fontFamily="$display">
|
||||
{mockup.title}
|
||||
</Text>
|
||||
<Button
|
||||
size="$3"
|
||||
backgroundColor="$primary"
|
||||
borderRadius="$pill"
|
||||
onPress={() => navigate(`/mockups/home/${mockup.id}`)}
|
||||
>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Text fontSize="$3" color="white">
|
||||
View
|
||||
</Text>
|
||||
<ArrowRight size={16} color="white" />
|
||||
</XStack>
|
||||
</Button>
|
||||
</XStack>
|
||||
<MockupLabel>{mockup.description}</MockupLabel>
|
||||
</MockupCard>
|
||||
))}
|
||||
</YStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
82
resources/js/guest-v2/screens/mockups/MockupsIndexScreen.tsx
Normal file
82
resources/js/guest-v2/screens/mockups/MockupsIndexScreen.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
import MockupFrame from './MockupFrame';
|
||||
import { MockupCard, MockupLabel } from './MockupPrimitives';
|
||||
|
||||
const mockups = [
|
||||
{ id: '1', title: 'Capture Orbit', description: 'Full-screen capture hub with orbiting actions.' },
|
||||
{ id: '2', title: 'Gallery Mosaic', description: 'Image-first grid with filters and fast scan.' },
|
||||
{ id: '3', title: 'Prompt Quest', description: 'Prompt hero with progress and task ladder.' },
|
||||
{ id: '4', title: 'Timeline Stream', description: 'Chronological feed with time markers.' },
|
||||
{ id: '5', title: 'Compass Hub', description: 'Quadrant navigation around a central action.' },
|
||||
{ id: '6', title: 'Split Capture', description: 'Camera preview plus quick tools and queue.' },
|
||||
{ id: '7', title: 'Swipe Deck', description: 'Stacked cards for rapid review.' },
|
||||
{ id: '8', title: 'Daybook', description: 'Morning/afternoon/night memory sections.' },
|
||||
{ id: '9', title: 'Checklist Flow', description: 'Tasks checklist paired with gallery progress.' },
|
||||
{ id: '10', title: 'Spotlight Reel', description: 'Live highlight reel with action strip.' },
|
||||
];
|
||||
|
||||
export default function MockupsIndexScreen() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<MockupFrame
|
||||
title="Guest PWA mockups"
|
||||
subtitle="10 layout concepts for the new event experience"
|
||||
>
|
||||
<MockupCard gap="$2">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack gap="$1">
|
||||
<Text fontSize="$5" fontWeight="$8" fontFamily="$display">
|
||||
Home concepts
|
||||
</Text>
|
||||
<MockupLabel>Explore 10 start screen ideas.</MockupLabel>
|
||||
</YStack>
|
||||
<Button
|
||||
size="$3"
|
||||
backgroundColor="$primary"
|
||||
borderRadius="$pill"
|
||||
onPress={() => navigate('/mockups/home')}
|
||||
>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Text fontSize="$3" color="white">
|
||||
Open
|
||||
</Text>
|
||||
<ArrowRight size={16} color="white" />
|
||||
</XStack>
|
||||
</Button>
|
||||
</XStack>
|
||||
</MockupCard>
|
||||
|
||||
<YStack gap="$3">
|
||||
{mockups.map((mockup) => (
|
||||
<MockupCard key={mockup.id} gap="$2">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$5" fontWeight="$8" fontFamily="$display">
|
||||
{mockup.title}
|
||||
</Text>
|
||||
<Button
|
||||
size="$3"
|
||||
backgroundColor="$primary"
|
||||
borderRadius="$pill"
|
||||
onPress={() => navigate(`/mockups/${mockup.id}`)}
|
||||
>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Text fontSize="$3" color="white">
|
||||
View
|
||||
</Text>
|
||||
<ArrowRight size={16} color="white" />
|
||||
</XStack>
|
||||
</Button>
|
||||
</XStack>
|
||||
<MockupLabel>{mockup.description}</MockupLabel>
|
||||
</MockupCard>
|
||||
))}
|
||||
</YStack>
|
||||
</MockupFrame>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user