{s.name} {s.sub}
{s.what}
PH
// Shared · Session Timings — the three daily trading sessions with live
// countdowns, shown as a "Sessions" tab in BOTH the student and admin portals.
// Exposes window.SessionTimings({ onGoSupport }).
//
// Difference from the public homepage version: the Telegram buttons do NOT
// link anywhere. Invite links rotate, so a hardcoded link in the portal goes
// stale and members end up on a dead URL. Clicking opens a dialog telling them
// to get the current link from their coach, with a button through to Support.
//
// All time math is done in Philippine Time (UTC+8) derived from UTC, so the
// countdown is identical for every member regardless of device timezone.
// PH has no DST, so the +8 offset is safe year-round.
(function(){
const { useState, useEffect, useRef } = React;
const SESSIONS = [
{ key:'asian', name:'Asian', sub:'Session', hour:7, min:0, time:'7:00', ap:'AM',
what:'Signal via Telegram',
flags:[['ph','Philippines'],['sg','Singapore'],['jp','Japan']] },
{ key:'london', name:'London', sub:'Killzone Session', hour:16, min:0, time:'4:00', ap:'PM',
what:'Daily LIVE trading with community',
flags:[['gb','United Kingdom'],['de','Germany']] },
{ key:'ny', name:'New York', sub:'Opening', hour:21, min:30, time:'9:30', ap:'PM',
what:'Daily LIVE trading with community',
flags:[['us','United States'],['ca','Canada']] },
];
const TG_PATH = "M21.9 4.3 18.9 19c-.2 1-.8 1.3-1.7.8l-4.6-3.4-2.2 2.1c-.3.3-.5.5-1 .5l.3-4.7 8.6-7.8c.4-.3-.1-.5-.6-.2L6.9 13.1 2.4 11.7c-1-.3-1-1 .2-1.5l18-6.9c.8-.3 1.5.2 1.3 1z";
const TgIcon = ({cls}) => ;
// PH wall-clock = UTC + 8h. Adding 8h lets getUTC* read as PH local time.
function phNow(){ return new Date(Date.now() + 8*3600000); }
// Next Mon-Fri occurrence of a PH hour:min. Sessions run 60 minutes.
function nextSession(ph, hour, min){
var c = new Date(ph.getTime());
c.setUTCHours(hour, min, 0, 0);
for (var i = 0; i < 8; i++){
var day = c.getUTCDay();
if (day >= 1 && day <= 5){
var start = c.getTime(), end = start + 3600000;
if (ph.getTime() < end) return { start:start, end:end, during: ph.getTime() >= start };
}
c.setTime(c.getTime() + 86400000);
c.setUTCHours(hour, min, 0, 0);
}
return { start:c.getTime(), end:c.getTime(), during:false };
}
// ph-space epoch -> real epoch. phNow() is Date.now()+8h, so every timestamp
// derived from it carries that same +8h shift; subtract it to get real UTC.
function realEpoch(phEpoch){ return phEpoch - 8*3600000; }
// The session's PH time expressed in the member's own zone. Derived from the
// actual next-occurrence timestamp, so their local DST is handled correctly —
// "4:00 PM PH" is 9:00 AM in London during BST but 8:00 AM in GMT.
function inZone(phEpoch, tz){
if(!tz) return null;
try{
return new Date(realEpoch(phEpoch))
.toLocaleTimeString('en-US',{timeZone:tz, hour:'numeric', minute:'2-digit'});
}catch(e){ return null; }
}
function Countdown({hour, min, tz, onStart}){
const [s, setS] = useState(()=>nextSession(phNow(), hour, min));
useEffect(()=>{
const t = setInterval(()=>setS(nextSession(phNow(), hour, min)), 1000);
return ()=>clearInterval(t);
},[hour,min]);
useEffect(()=>{ if(onStart) onStart(s.start); },[s.start]);
const left = (s.during ? s.end : s.start) - phNow().getTime();
const ms = left < 0 ? 0 : left;
let sec = Math.floor(ms/1000);
const d = Math.floor(sec/86400); sec -= d*86400;
const h = Math.floor(sec/3600); sec -= h*3600;
const m = Math.floor(sec/60); sec -= m*60;
const U = ({v,u}) =>
Our Telegram invite links are rotated regularly to keep the channels private to paying members, so we don't publish a permanent link here.
To get the current link: message your assigned coach directly — they'll send you the active invite. You can also check the live trade announcement channel listed under Support.
Monday — Friday · all times in Philippine Time
{tz &&Also shown in your timezone · {tz.replace(/_/g,' ')}
} {!tz &&Set your timezone in Account to see these in your local time
}{s.what}