Skip to content

Commit 787e3e6

Browse files
committed
feat: Add PWA support, QR sharing, and brand splash fixes
1 parent a2c290f commit 787e3e6

9 files changed

Lines changed: 140 additions & 12 deletions

File tree

frontend/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>Zappify Shoes</title>
8+
<link rel="manifest" href="/manifest.json" />
9+
<meta name="theme-color" content="#FF3D00" />
10+
<meta name="apple-mobile-web-app-capable" content="yes" />
11+
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
12+
<link rel="apple-touch-icon" href="/logo.png" />
813
</head>
914
<body>
1015
<div id="root"></div>

frontend/public/logo.png

390 KB
Loading

frontend/public/manifest.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "Zappify Shoes",
3+
"short_name": "Zappify",
4+
"description": "Premium Shoe Store Experience.",
5+
"start_url": "/",
6+
"display": "standalone",
7+
"background_color": "#FF3D00",
8+
"theme_color": "#FF3D00",
9+
"orientation": "portrait",
10+
"icons": [
11+
{
12+
"src": "/logo.png",
13+
"sizes": "192x192",
14+
"type": "image/png",
15+
"purpose": "any maskable"
16+
},
17+
{
18+
"src": "/logo.png",
19+
"sizes": "512x512",
20+
"type": "image/png",
21+
"purpose": "any maskable"
22+
}
23+
]
24+
}

frontend/src/App.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ function App() {
128128

129129
return (
130130
<AnimatePresence mode="wait">
131-
{showSplash ? (
131+
{showSplash && !isEmbed ? (
132132
<SplashScreen key="splash" />
133133
) : (
134134
<motion.div
@@ -281,7 +281,7 @@ const SplashScreen = () => (
281281
}}
282282
>
283283
<div className="splash-logo">
284-
<span>Z</span>appify
284+
<img src="/logo.png" alt="Zappify" className="splash-logo-img" />
285285
</div>
286286
<div className="splash-subtitle">Premium Shoe Store</div>
287287
<motion.div

frontend/src/Preview.jsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default function Preview() {
4444
transition={{ duration: 0.8, ease: "easeOut" }}
4545
className="align-center"
4646
>
47-
<div className="preview-logo-text">Zappify</div>
47+
<img src="/logo.png" alt="Zappify" className="preview-logo-img" />
4848
<div className="preview-logo-subtitle">Premium Shoes</div>
4949
<div className="preview-spinner" />
5050
</motion.div>
@@ -99,6 +99,27 @@ export default function Preview() {
9999
<div className="home-bar" />
100100
</div>
101101
</div>
102+
103+
<motion.div
104+
className="qr-section"
105+
initial={{ opacity: 0, y: 20 }}
106+
animate={{ opacity: 1, y: 0 }}
107+
transition={{ delay: 1, duration: 0.5 }}
108+
>
109+
<div className="qr-text">
110+
<h3>Experience on Mobile</h3>
111+
<p>Scan to see the real Zappify app on your phone</p>
112+
</div>
113+
<div className="qr-code-wrapper">
114+
<img src={`https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${encodeURIComponent(window.location.origin)}`} alt="QR Code" />
115+
</div>
116+
<button className="share-btn" onClick={() => {
117+
navigator.clipboard.writeText(window.location.origin);
118+
alert("Link copied! Share it with anyone.");
119+
}}>
120+
Copy App Link
121+
</button>
122+
</motion.div>
102123
</div>
103124
</div>
104125
);

frontend/src/index.css

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,8 @@ ul {
12371237
border: 3px solid rgba(255, 255, 255, 0.3);
12381238
border-top-color: white;
12391239
border-radius: 50%;
1240+
margin-left: auto;
1241+
margin-right: auto;
12401242
animation: splash-spin 0.8s linear infinite;
12411243
}
12421244

@@ -1293,14 +1295,21 @@ ul {
12931295
border: 3px solid rgba(255,255,255,0.3);
12941296
border-top-color: #fff;
12951297
border-radius: 50%;
1298+
margin-left: auto;
1299+
margin-right: auto;
12961300
animation: preview-spin 0.8s linear infinite;
12971301
}
12981302

12991303
@keyframes preview-spin {
13001304
to { transform: rotate(360deg); }
13011305
}
13021306

1303-
.align-center { text-align: center; }
1307+
.align-center {
1308+
display: flex;
1309+
flex-direction: column;
1310+
align-items: center;
1311+
text-align: center;
1312+
}
13041313

13051314
.phone-header-wrapper {
13061315
position: absolute;
@@ -1487,3 +1496,73 @@ ul {
14871496
border-radius: 3px;
14881497
margin-top: 10px;
14891498
}
1499+
1500+
.splash-logo-img {
1501+
width: clamp(150px, 25vw, 250px);
1502+
max-height: 250px;
1503+
object-fit: contain;
1504+
}
1505+
1506+
.preview-logo-img {
1507+
width: 140px;
1508+
height: auto;
1509+
object-fit: contain;
1510+
margin-bottom: 20px;
1511+
}
1512+
1513+
.qr-section {
1514+
margin-top: 40px;
1515+
display: flex;
1516+
flex-direction: column;
1517+
align-items: center;
1518+
gap: 15px;
1519+
background: rgba(255, 255, 255, 0.05);
1520+
padding: 24px;
1521+
border-radius: 24px;
1522+
border: 1px solid rgba(255, 255, 255, 0.1);
1523+
backdrop-filter: blur(10px);
1524+
}
1525+
1526+
.qr-code-wrapper {
1527+
background: white;
1528+
padding: 12px;
1529+
border-radius: 16px;
1530+
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
1531+
}
1532+
1533+
.qr-code-wrapper img {
1534+
display: block;
1535+
}
1536+
1537+
.qr-text {
1538+
color: #fff;
1539+
text-align: center;
1540+
}
1541+
1542+
.qr-text h3 {
1543+
margin: 0;
1544+
font-size: 18px;
1545+
font-weight: 700;
1546+
}
1547+
1548+
.qr-text p {
1549+
margin: 5px 0 0;
1550+
font-size: 13px;
1551+
opacity: 0.6;
1552+
}
1553+
1554+
.share-btn {
1555+
margin-top: 10px;
1556+
background: var(--brand-red);
1557+
color: white;
1558+
border: none;
1559+
padding: 10px 20px;
1560+
border-radius: 12px;
1561+
font-weight: 600;
1562+
cursor: pointer;
1563+
transition: transform 0.2s;
1564+
}
1565+
1566+
.share-btn:hover {
1567+
transform: scale(1.05);
1568+
}

mobile/App.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'react-native-gesture-handler';
22
import React, { useState, useEffect, useRef } from 'react';
3-
import { View, Text, StyleSheet, Animated, StatusBar } from 'react-native';
3+
import { View, Text, StyleSheet, Animated, StatusBar, Image } from 'react-native';
44
import { NavigationContainer } from '@react-navigation/native';
55
import { createNativeStackNavigator } from '@react-navigation/native-stack';
66
import { SafeAreaProvider } from 'react-native-safe-area-context';
@@ -46,7 +46,7 @@ export default function App() {
4646
<StatusBar backgroundColor="#FF3D00" barStyle="light-content" />
4747
<Animated.View style={[styles.splashContainer, { opacity: fadeAnim }]}>
4848
<Animated.View style={{ transform: [{ scale: scaleAnim }], alignItems: 'center' }}>
49-
<Text style={styles.splashLogo}>Zappify</Text>
49+
<Image source={require('./assets/logo.png')} style={styles.splashLogoImg} />
5050
<Text style={styles.splashSubtitle}>Premium Shoe Store</Text>
5151
</Animated.View>
5252
</Animated.View>
@@ -80,11 +80,10 @@ const styles = StyleSheet.create({
8080
justifyContent: 'center',
8181
alignItems: 'center',
8282
},
83-
splashLogo: {
84-
fontSize: 64,
85-
fontWeight: '900',
86-
color: '#FFFFFF',
87-
letterSpacing: -3,
83+
splashLogoImg: {
84+
width: 280,
85+
height: 280,
86+
resizeMode: 'contain',
8887
},
8988
splashSubtitle: {
9089
fontSize: 12,

mobile/app.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"userInterfaceStyle": "light",
99
"newArchEnabled": true,
1010
"splash": {
11-
"image": "./assets/splash-icon.png",
11+
"image": "./assets/logo.png",
1212
"resizeMode": "contain",
1313
"backgroundColor": "#FF3D00"
1414
},

mobile/assets/logo.png

390 KB
Loading

0 commit comments

Comments
 (0)