// SHOT — Screen components (atoms + onboarding flow)
(function(){
const { useState, useEffect, useRef } = React;
const { FRIENDS, EVENTS, INTERESTS } = window.SHOT_DATA;
/* ════════════════════════════════════════════════════
ATOMS
════════════════════════════════════════════════════ */
const StatusBar = ({ time = '21:47' }) => (
);
const TopNav = ({ title, onBack, action, compact }) => (
{onBack ?
:
}
{title}
{action ||
}
);
const Icon = ({ name, size = 20, stroke = 'currentColor' }) => {
const paths = {
map: <> >,
feed: <> >,
event: <> >,
profile: <> >,
bell: <> >,
search: <> >,
settings:<> >,
chat: <> >,
share: <> >,
heart: <> >,
bookmark:<> >,
clock: <> >,
pin: <> >,
plus: <> >,
user: <> >,
cam: <> >,
lock: <> >,
globe: <> >,
info: <> >,
logout: <> >,
filter: <> >,
text: <> >,
sticker: <> >,
};
return (
{paths[name] || null}
);
};
const BottomNav = ({ tab, onTab, onCenter }) => (
onTab('map')}>
Map
onTab('feed')}>
Feed
onTab('events')}>
Events
onTab('profile')}>
Profil
);
const AmbianceDot = ({ vibe }) => {
const colors = { calm: 'var(--amb-calm)', anime: 'var(--amb-anime)', hot: 'var(--amb-hot)', fire: 'var(--amb-fire)' };
return ;
};
const vibeLabel = (v) => ({ calm: 'Calme', anime: 'Animé', hot: 'Chaud', fire: 'Blindé' })[v];
/* ════════════════════════════════════════════════════
SCREEN: SPLASH
════════════════════════════════════════════════════ */
const SplashScreen = ({ onDone }) => {
useEffect(() => { const t = setTimeout(onDone, 1400); return () => clearTimeout(t); }, []);
return (
<>
SHOT.
Le réseau social des bars
Chargement…
>
);
};
/* ════════════════════════════════════════════════════
SCREEN: ONBOARDING
════════════════════════════════════════════════════ */
const ONB_SLIDES = [
{
title: <>Découvre les barsautour de toi. >,
desc: "Une carte vivante en temps réel. L'ambiance, l'affluence, les promos — tout, en un coup d'œil.",
vis: 'map'
},
{
title: <>Check-in avectes potes. >,
desc: "Préviens tes amis quand tu pars, retrouve-les en un tap. Les soirs deviennent moins solos.",
vis: 'friends'
},
{
title: <>Toutes les soiréesau même endroit. >,
desc: "Les events BDE, les soirées partenaires, les happy hours. RSVP en deux secondes.",
vis: 'events'
}
];
const OnbVis = ({ kind }) => {
if (kind === 'map') return (
);
if (kind === 'friends') return (
{FRIENDS.slice(0,3).map(f => (
{f.initials}
{f.live && }
))}
);
return (
{EVENTS.slice(0,2).map(e => (
{e.title}
{e.bar} · {e.time}
))}
);
};
const OnboardingScreen = ({ idx, onNext, onSkip, onSignup }) => {
const slide = ONB_SLIDES[idx];
const isLast = idx === ONB_SLIDES.length - 1;
return (
<>
{ONB_SLIDES.map((_,i) =>
)}
{slide.title}
{slide.desc}
{isLast ? 'Commencer' : 'Suivant'}
>
);
};
/* ════════════════════════════════════════════════════
SCREEN: SIGNUP / VERIFY / INTERESTS
════════════════════════════════════════════════════ */
const SignupScreen = ({ onBack, onNext }) => (
<>
>
);
const VerifyScreen = ({ onBack, onNext }) => {
const [code] = useState(['4', '8', '2', '1', '', '']);
return (
<>
Vérification
On vient d'envoyer un code à 6 chiffres au +33 6 12 34 56 78 .
{code.map((c, i) =>
{c}
)}
Pas reçu ? Renvoyer dans 0:42
Vérifier
>
);
};
const InterestsScreen = ({ onNext, onBack }) => {
const [sel, setSel] = useState(new Set(['wine','craft','cock']));
const toggle = (id) => {
setSel(s => { const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n; });
};
return (
<>
Tes ambiances préférées
Sélectionne au moins 3 styles. On personnalise ta carte et ton feed.
{INTERESTS.map(it => (
toggle(it.id)}>
{it.icon}
{it.label}
))}
Continuer ({sel.size} sélectionnés)
>
);
};
window.SHOT_SCREENS_1 = { StatusBar, TopNav, BottomNav, Icon, AmbianceDot, vibeLabel, SplashScreen, OnboardingScreen, SignupScreen, VerifyScreen, InterestsScreen };
})();