Hero Banner
Controls the full-bleed promotional banner on the app home screen.
Live preview
ANNO 1714 · STETTYN
New Season Releases
Hand-crafted wines from the heart of Villiersdorp, Western Cape.
SHOP NOW →
#1B2E22
Promotions
Manage the promotional cards shown in the app. Drag to reorder.
Loading promotions…
Push Notifications
Send notifications to Stettyn app users instantly.
Registered devices:
Loading…
Delivered via Expo Push Service
Sent history
No notifications sent yet.
Integration Guide
How to connect the Stettyn mobile app to this admin panel.
1 · Create a Firebase project
- Go to console.firebase.google.com and create a project called stettyn-app.
- Add a Web app to the project — copy the config object.
- Open this HTML file in a text editor and replace the
REPLACE_WITH_YOUR_*placeholders at the bottom with your config values. - In Firebase Console → Authentication → Sign-in methods → enable Email/Password.
- Create an admin user account via Authentication → Add user.
- In Firestore → Create database → Start in test mode (tighten rules before production).
2 · Update the mobile app — read from Firestore
Install the Firebase SDK in the app:
npx expo install @react-native-firebase/app @react-native-firebase/firestore
Create src/utils/firebaseConfig.ts:
import firebase from '@react-native-firebase/app';
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_PROJECT.firebaseapp.com",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_PROJECT.appspot.com",
messagingSenderId: "YOUR_SENDER_ID",
appId: "YOUR_APP_ID",
};
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
export default firebase;
Replace src/data/promotions.ts usage with a hook:
// src/hooks/usePromotions.ts
import { useState, useEffect } from 'react';
import firestore from '@react-native-firebase/firestore';
import { SEED_PROMOTIONS } from '../data/promotions'; // fallback
export function usePromotions() {
const [promotions, setPromotions] = useState(SEED_PROMOTIONS);
useEffect(() => {
const unsub = firestore()
.collection('promotions')
.orderBy('order')
.where('active', '==', true)
.onSnapshot(snap => {
if (!snap.empty) {
setPromotions(snap.docs.map(d => ({ id: d.id, ...d.data() })) as any);
}
});
return unsub;
}, []);
return promotions;
}
// src/hooks/useHeroBanner.ts
import { useState, useEffect } from 'react';
import firestore from '@react-native-firebase/firestore';
export function useHeroBanner() {
const [hero, setHero] = useState<any>(null);
useEffect(() => {
const unsub = firestore()
.doc('config/hero')
.onSnapshot(snap => { if (snap.exists) setHero(snap.data()); });
return unsub;
}, []);
return hero;
}
3 · Enable push notifications
Install Expo notifications:
npx expo install expo-notifications
Register the device token and save it to Firestore (add to App.tsx once authenticated):
import * as Notifications from 'expo-notifications';
import firestore from '@react-native-firebase/firestore';
async function registerForPushNotifications(userId: string) {
const { status } = await Notifications.requestPermissionsAsync();
if (status !== 'granted') return;
const token = (await Notifications.getExpoPushTokenAsync()).data;
// Save token to Firestore so admin panel can reach this device
await firestore().collection('pushTokens').doc(userId).set({
token,
tier: profile.tier,
updatedAt: firestore.FieldValue.serverTimestamp(),
});
}
The admin panel reads these tokens and sends via the Expo Push API when you hit "Send now".
4 · Firestore security rules (before production)
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Admin writes — locked to your admin email
match /config/{doc} {
allow read: if true;
allow write: if request.auth.token.email == 'admin@stettynwines.co.za';
}
match /promotions/{doc} {
allow read: if true;
allow write: if request.auth.token.email == 'admin@stettynwines.co.za';
}
// Push tokens — authenticated users write their own, admin reads all
match /pushTokens/{userId} {
allow write: if request.auth.uid == userId;
allow read: if request.auth.token.email == 'admin@stettynwines.co.za';
}
match /notificationHistory/{doc} {
allow read, write: if request.auth.token.email == 'admin@stettynwines.co.za';
}
}
}