@cuemath/leap 3.3.7-link.0 → 3.3.8-aas1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/features/auth/pla-signup/pla-analytics-events.js +4 -10
  2. package/dist/features/auth/pla-signup/pla-analytics-events.js.map +1 -1
  3. package/dist/features/class-timer/animate.js +103 -0
  4. package/dist/features/class-timer/animate.js.map +1 -0
  5. package/dist/features/class-timer/animations/open-close.js +102 -0
  6. package/dist/features/class-timer/animations/open-close.js.map +1 -0
  7. package/dist/features/class-timer/animations/ripple.js +44 -0
  8. package/dist/features/class-timer/animations/ripple.js.map +1 -0
  9. package/dist/features/class-timer/class-timer.js +155 -0
  10. package/dist/features/class-timer/class-timer.js.map +1 -0
  11. package/dist/features/class-timer/clock.js +26 -0
  12. package/dist/features/class-timer/clock.js.map +1 -0
  13. package/dist/features/class-timer/constants.js +27 -0
  14. package/dist/features/class-timer/constants.js.map +1 -0
  15. package/dist/features/class-timer/timer.js +68 -0
  16. package/dist/features/class-timer/timer.js.map +1 -0
  17. package/dist/features/hooks/use-visibility-change.js +12 -0
  18. package/dist/features/hooks/use-visibility-change.js.map +1 -0
  19. package/dist/features/ui/constants/z-index.js +4 -1
  20. package/dist/features/ui/constants/z-index.js.map +1 -1
  21. package/dist/features/ui/inputs/base-select-input/select-section/select-section.js +12 -11
  22. package/dist/features/ui/inputs/base-select-input/select-section/select-section.js.map +1 -1
  23. package/dist/features/utils/utils.js +18 -18
  24. package/dist/features/utils/utils.js.map +1 -1
  25. package/dist/features/worksheet/worksheet/worksheet-behavior-helper.js +38 -38
  26. package/dist/features/worksheet/worksheet/worksheet-behavior-helper.js.map +1 -1
  27. package/dist/features/worksheet/worksheet/worksheet-questions-controller/worksheet-questions-controller.js +128 -126
  28. package/dist/features/worksheet/worksheet/worksheet-questions-controller/worksheet-questions-controller.js.map +1 -1
  29. package/dist/index.d.ts +65 -7
  30. package/dist/index.js +524 -514
  31. package/dist/index.js.map +1 -1
  32. package/package.json +3 -2
@@ -1,6 +1,6 @@
1
1
  import { PLUGINS as _ } from "../../../node_modules/@cuemath/analytics-v2/dist/constants.js";
2
- var s = /* @__PURE__ */ ((e) => (e.START_SIGNUP_CTA_CLICKED = "start_signup_cta_clicked", e.ECNA_STEP_VIEWED = "ecna_step_viewed", e.ECNA_RESPONSE_RECORDED_DEBUG = "ecna_response_recorded_debug", e.PARENT_SIGNUP_CTA_CLICKED = "parent_signup_cta_clicked", e.PARENT_SIGNUP_SUCCESSFUL = "parent_signup_successful", e.PARENT_SIGNUP_FAILED = "parent_signup_failed", e.STUDENT_SIGNUP_SUCCESSFUL = "signup_successful", e.STUDENT_SIGNUP_FAILED = "signup_failed", e.SIGNUP_OTP_ENTERED = "signup_otp_entered", e.SIGNUP_OTP_VERIFIED = "signup_otp_verified", e.SIGNUP_OTP_FAILED = "signup_otp_failed", e.SLOTS_SHOWN = "slots_shown", e.SLOT_DATE_SELECTED = "slot_date_selected", e.SLOT_TIME_SELECTED = "slot_time_selected", e.SUBSCRIPTION_INTENT_FAILED = "subscription_intent_failed", e.SUBSCRIPTION_INTENT_CREATED = "subscription_intent_created", e.STRIPE_PAYMENT_ELEMENT_READY = "stripe_payment_element_ready", e.STRIPE_PAYMENT_FAILED = "stripe_payment_failed", e.STRIPE_PAYMENT_SUCCESS = "stripe_payment_success", e.PAYMENT_PLAN_SELECTED = "payment_plan_selected", e))(s || {});
3
- const n = {
2
+ var s = /* @__PURE__ */ ((e) => (e.START_SIGNUP_CTA_CLICKED = "start_signup_cta_clicked", e.ECNA_STEP_VIEWED = "ecna_step_viewed", e.ECNA_RESPONSE_RECORDED_DEBUG = "ecna_response_recorded_debug", e.PARENT_SIGNUP_CTA_CLICKED = "parent_signup_cta_clicked", e.PARENT_SIGNUP_SUCCESSFUL = "parent_signup_successful", e.PARENT_SIGNUP_FAILED = "parent_signup_failed", e.STUDENT_SIGNUP_SUCCESSFUL = "signup_successful", e.STUDENT_SIGNUP_FAILED = "signup_failed", e.SIGNUP_OTP_ENTERED = "signup_otp_entered", e.SIGNUP_OTP_VERIFIED = "signup_otp_verified", e.SIGNUP_OTP_FAILED = "signup_otp_failed", e.SLOTS_SHOWN = "slots_shown", e.SLOT_DATE_SELECTED = "slot_date_selected", e.SLOT_TIME_SELECTED = "slot_time_selected", e))(s || {});
3
+ const i = {
4
4
  start_signup_cta_clicked: [_.MIXPANEL],
5
5
  ecna_step_viewed: [_.MIXPANEL],
6
6
  ecna_response_recorded_debug: [_.MIXPANEL],
@@ -14,16 +14,10 @@ const n = {
14
14
  signup_otp_failed: [_.MIXPANEL],
15
15
  slots_shown: [_.MIXPANEL],
16
16
  slot_date_selected: [_.MIXPANEL],
17
- slot_time_selected: [_.MIXPANEL],
18
- subscription_intent_failed: [_.MIXPANEL],
19
- subscription_intent_created: [_.MIXPANEL],
20
- stripe_payment_element_ready: [_.MIXPANEL],
21
- stripe_payment_failed: [_.MIXPANEL],
22
- stripe_payment_success: [_.MIXPANEL],
23
- payment_plan_selected: [_.MIXPANEL]
17
+ slot_time_selected: [_.MIXPANEL]
24
18
  };
25
19
  export {
26
20
  s as PLA_ANALYTICS_EVENTS,
27
- n as PLA_ANALYTICS_WHITELIST_EVENTS
21
+ i as PLA_ANALYTICS_WHITELIST_EVENTS
28
22
  };
29
23
  //# sourceMappingURL=pla-analytics-events.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pla-analytics-events.js","sources":["../../../../src/features/auth/pla-signup/pla-analytics-events.ts"],"sourcesContent":["import { PLUGINS } from '@cuemath/analytics-v2/dist/constants';\n\nexport enum PLA_ANALYTICS_EVENTS {\n START_SIGNUP_CTA_CLICKED = 'start_signup_cta_clicked',\n ECNA_STEP_VIEWED = 'ecna_step_viewed',\n ECNA_RESPONSE_RECORDED_DEBUG = 'ecna_response_recorded_debug',\n PARENT_SIGNUP_CTA_CLICKED = 'parent_signup_cta_clicked',\n PARENT_SIGNUP_SUCCESSFUL = 'parent_signup_successful',\n PARENT_SIGNUP_FAILED = 'parent_signup_failed',\n STUDENT_SIGNUP_SUCCESSFUL = 'signup_successful',\n STUDENT_SIGNUP_FAILED = 'signup_failed',\n SIGNUP_OTP_ENTERED = 'signup_otp_entered',\n SIGNUP_OTP_VERIFIED = 'signup_otp_verified',\n SIGNUP_OTP_FAILED = 'signup_otp_failed',\n SLOTS_SHOWN = 'slots_shown',\n SLOT_DATE_SELECTED = 'slot_date_selected',\n SLOT_TIME_SELECTED = 'slot_time_selected',\n SUBSCRIPTION_INTENT_FAILED = 'subscription_intent_failed',\n SUBSCRIPTION_INTENT_CREATED = 'subscription_intent_created',\n STRIPE_PAYMENT_ELEMENT_READY = 'stripe_payment_element_ready',\n STRIPE_PAYMENT_FAILED = 'stripe_payment_failed',\n STRIPE_PAYMENT_SUCCESS = 'stripe_payment_success',\n PAYMENT_PLAN_SELECTED = 'payment_plan_selected',\n}\n\nexport const PLA_ANALYTICS_WHITELIST_EVENTS = {\n [PLA_ANALYTICS_EVENTS.START_SIGNUP_CTA_CLICKED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.ECNA_STEP_VIEWED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.ECNA_RESPONSE_RECORDED_DEBUG]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.PARENT_SIGNUP_CTA_CLICKED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.PARENT_SIGNUP_SUCCESSFUL]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.PARENT_SIGNUP_FAILED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.STUDENT_SIGNUP_SUCCESSFUL]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.STUDENT_SIGNUP_FAILED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SIGNUP_OTP_ENTERED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SIGNUP_OTP_VERIFIED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SIGNUP_OTP_FAILED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SLOTS_SHOWN]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SLOT_DATE_SELECTED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SLOT_TIME_SELECTED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SUBSCRIPTION_INTENT_FAILED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SUBSCRIPTION_INTENT_CREATED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.STRIPE_PAYMENT_ELEMENT_READY]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.STRIPE_PAYMENT_FAILED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.STRIPE_PAYMENT_SUCCESS]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.PAYMENT_PLAN_SELECTED]: [PLUGINS.MIXPANEL],\n};\n"],"names":["PLA_ANALYTICS_EVENTS","PLA_ANALYTICS_WHITELIST_EVENTS","PLUGINS"],"mappings":";AAEY,IAAAA,sBAAAA,OACVA,EAAA,2BAA2B,4BAC3BA,EAAA,mBAAmB,oBACnBA,EAAA,+BAA+B,gCAC/BA,EAAA,4BAA4B,6BAC5BA,EAAA,2BAA2B,4BAC3BA,EAAA,uBAAuB,wBACvBA,EAAA,4BAA4B,qBAC5BA,EAAA,wBAAwB,iBACxBA,EAAA,qBAAqB,sBACrBA,EAAA,sBAAsB,uBACtBA,EAAA,oBAAoB,qBACpBA,EAAA,cAAc,eACdA,EAAA,qBAAqB,sBACrBA,EAAA,qBAAqB,sBACrBA,EAAA,6BAA6B,8BAC7BA,EAAA,8BAA8B,+BAC9BA,EAAA,+BAA+B,gCAC/BA,EAAA,wBAAwB,yBACxBA,EAAA,yBAAyB,0BACzBA,EAAA,wBAAwB,yBApBdA,IAAAA,KAAA,CAAA,CAAA;AAuBL,MAAMC,IAAiC;AAAA,EAC3C,0BAAgD,CAACC,EAAQ,QAAQ;AAAA,EACjE,kBAAwC,CAACA,EAAQ,QAAQ;AAAA,EACzD,8BAAoD,CAACA,EAAQ,QAAQ;AAAA,EACrE,2BAAiD,CAACA,EAAQ,QAAQ;AAAA,EAClE,0BAAgD,CAACA,EAAQ,QAAQ;AAAA,EACjE,sBAA4C,CAACA,EAAQ,QAAQ;AAAA,EAC7D,mBAAiD,CAACA,EAAQ,QAAQ;AAAA,EAClE,eAA6C,CAACA,EAAQ,QAAQ;AAAA,EAC9D,oBAA0C,CAACA,EAAQ,QAAQ;AAAA,EAC3D,qBAA2C,CAACA,EAAQ,QAAQ;AAAA,EAC5D,mBAAyC,CAACA,EAAQ,QAAQ;AAAA,EAC1D,aAAmC,CAACA,EAAQ,QAAQ;AAAA,EACpD,oBAA0C,CAACA,EAAQ,QAAQ;AAAA,EAC3D,oBAA0C,CAACA,EAAQ,QAAQ;AAAA,EAC3D,4BAAkD,CAACA,EAAQ,QAAQ;AAAA,EACnE,6BAAmD,CAACA,EAAQ,QAAQ;AAAA,EACpE,8BAAoD,CAACA,EAAQ,QAAQ;AAAA,EACrE,uBAA6C,CAACA,EAAQ,QAAQ;AAAA,EAC9D,wBAA8C,CAACA,EAAQ,QAAQ;AAAA,EAC/D,uBAA6C,CAACA,EAAQ,QAAQ;AACjE;"}
1
+ {"version":3,"file":"pla-analytics-events.js","sources":["../../../../src/features/auth/pla-signup/pla-analytics-events.ts"],"sourcesContent":["import { PLUGINS } from '@cuemath/analytics-v2/dist/constants';\n\nexport enum PLA_ANALYTICS_EVENTS {\n START_SIGNUP_CTA_CLICKED = 'start_signup_cta_clicked',\n ECNA_STEP_VIEWED = 'ecna_step_viewed',\n ECNA_RESPONSE_RECORDED_DEBUG = 'ecna_response_recorded_debug',\n PARENT_SIGNUP_CTA_CLICKED = 'parent_signup_cta_clicked',\n PARENT_SIGNUP_SUCCESSFUL = 'parent_signup_successful',\n PARENT_SIGNUP_FAILED = 'parent_signup_failed',\n STUDENT_SIGNUP_SUCCESSFUL = 'signup_successful',\n STUDENT_SIGNUP_FAILED = 'signup_failed',\n SIGNUP_OTP_ENTERED = 'signup_otp_entered',\n SIGNUP_OTP_VERIFIED = 'signup_otp_verified',\n SIGNUP_OTP_FAILED = 'signup_otp_failed',\n SLOTS_SHOWN = 'slots_shown',\n SLOT_DATE_SELECTED = 'slot_date_selected',\n SLOT_TIME_SELECTED = 'slot_time_selected',\n}\n\nexport const PLA_ANALYTICS_WHITELIST_EVENTS = {\n [PLA_ANALYTICS_EVENTS.START_SIGNUP_CTA_CLICKED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.ECNA_STEP_VIEWED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.ECNA_RESPONSE_RECORDED_DEBUG]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.PARENT_SIGNUP_CTA_CLICKED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.PARENT_SIGNUP_SUCCESSFUL]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.PARENT_SIGNUP_FAILED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.STUDENT_SIGNUP_SUCCESSFUL]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.STUDENT_SIGNUP_FAILED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SIGNUP_OTP_ENTERED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SIGNUP_OTP_VERIFIED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SIGNUP_OTP_FAILED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SLOTS_SHOWN]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SLOT_DATE_SELECTED]: [PLUGINS.MIXPANEL],\n [PLA_ANALYTICS_EVENTS.SLOT_TIME_SELECTED]: [PLUGINS.MIXPANEL],\n};\n"],"names":["PLA_ANALYTICS_EVENTS","PLA_ANALYTICS_WHITELIST_EVENTS","PLUGINS"],"mappings":";AAEY,IAAAA,sBAAAA,OACVA,EAAA,2BAA2B,4BAC3BA,EAAA,mBAAmB,oBACnBA,EAAA,+BAA+B,gCAC/BA,EAAA,4BAA4B,6BAC5BA,EAAA,2BAA2B,4BAC3BA,EAAA,uBAAuB,wBACvBA,EAAA,4BAA4B,qBAC5BA,EAAA,wBAAwB,iBACxBA,EAAA,qBAAqB,sBACrBA,EAAA,sBAAsB,uBACtBA,EAAA,oBAAoB,qBACpBA,EAAA,cAAc,eACdA,EAAA,qBAAqB,sBACrBA,EAAA,qBAAqB,sBAdXA,IAAAA,KAAA,CAAA,CAAA;AAiBL,MAAMC,IAAiC;AAAA,EAC3C,0BAAgD,CAACC,EAAQ,QAAQ;AAAA,EACjE,kBAAwC,CAACA,EAAQ,QAAQ;AAAA,EACzD,8BAAoD,CAACA,EAAQ,QAAQ;AAAA,EACrE,2BAAiD,CAACA,EAAQ,QAAQ;AAAA,EAClE,0BAAgD,CAACA,EAAQ,QAAQ;AAAA,EACjE,sBAA4C,CAACA,EAAQ,QAAQ;AAAA,EAC7D,mBAAiD,CAACA,EAAQ,QAAQ;AAAA,EAClE,eAA6C,CAACA,EAAQ,QAAQ;AAAA,EAC9D,oBAA0C,CAACA,EAAQ,QAAQ;AAAA,EAC3D,qBAA2C,CAACA,EAAQ,QAAQ;AAAA,EAC5D,mBAAyC,CAACA,EAAQ,QAAQ;AAAA,EAC1D,aAAmC,CAACA,EAAQ,QAAQ;AAAA,EACpD,oBAA0C,CAACA,EAAQ,QAAQ;AAAA,EAC3D,oBAA0C,CAACA,EAAQ,QAAQ;AAC9D;"}
@@ -0,0 +1,103 @@
1
+ import { jsxs as f, Fragment as S, jsx as e } from "react/jsx-runtime";
2
+ import { memo as N, useState as k, useRef as w, useEffect as u, useCallback as c } from "react";
3
+ import r from "styled-components";
4
+ import O from "../../assets/line-icons/icons/plus.js";
5
+ import X from "../hooks/use-previous.js";
6
+ import D from "../ui/buttons/clickable/clickable.js";
7
+ import a from "../ui/layout/flex-view.js";
8
+ import m from "../ui/text/text.js";
9
+ import I from "./animations/open-close.js";
10
+ import { ANIMATION_TIME as i, TIME_LEFT_IDLE as F, LAST_FIVE as M, START_TIMER as z, EXTEND_IDLE as R } from "./constants.js";
11
+ const V = r(a)`
12
+ position: absolute;
13
+ top: -8px;
14
+ right: 8px;
15
+ z-index: ${({ theme: o }) => o.zIndex.EXTEND_CLASS_ANIMATION_3};
16
+ `, W = r(m)`
17
+ padding-left: 4px;
18
+ padding-right: 8px;
19
+ `, y = r(a)`
20
+ flex-flow: nowrap;
21
+ z-index: ${({ theme: o }) => o.zIndex.EXTEND_CLASS_ANIMATION_2};
22
+ `, v = r(a)`
23
+ position: fixed;
24
+ top: 0;
25
+ bottom: 0;
26
+ left: 0;
27
+ right: 0;
28
+ background: rgba(0, 0, 0, 0.4);
29
+ z-index: ${({ theme: o }) => o.zIndex.EXTEND_CLASS_ANIMATION_1};
30
+ `, j = (o) => {
31
+ const {
32
+ animateClock: t,
33
+ classStartedTime: E,
34
+ duration: x,
35
+ onAnimation: d = () => {
36
+ },
37
+ onExtendClass: C = () => {
38
+ },
39
+ setAnimateClock: p,
40
+ setStartTimer: A,
41
+ showExtendIcon: _ = !1
42
+ } = o, [$, s] = k(!1), n = Math.floor(x - (+/* @__PURE__ */ new Date() - E) / 1e3), h = _ && n <= i.LAST_FIVE, T = X(t), l = w(null);
43
+ u(() => {
44
+ t && !T && (l.current = setTimeout(() => {
45
+ s(!0);
46
+ }, 1e3));
47
+ }, [t, T]), u(() => () => {
48
+ l.current && clearTimeout(l.current);
49
+ }, []);
50
+ const b = c(() => {
51
+ p(!1);
52
+ }, [p]), g = c(() => {
53
+ A(!0), d();
54
+ }, [d, A]), L = c(() => {
55
+ s(!1);
56
+ }, [s]);
57
+ return /* @__PURE__ */ f(S, { children: [
58
+ n <= i.LAST_FIVE && t && /* @__PURE__ */ e(v, {}),
59
+ /* @__PURE__ */ e(
60
+ I,
61
+ {
62
+ background: n <= i.LAST_FIVE ? "ORANGE_4" : "YELLOW_3",
63
+ onAnimationComplete: b,
64
+ onOpenAnimationComplete: g,
65
+ visible: t,
66
+ idleTime: F,
67
+ children: /* @__PURE__ */ f(
68
+ y,
69
+ {
70
+ $flexDirection: "row",
71
+ $alignItems: "center",
72
+ $width: "100%",
73
+ $justifyContent: "space-around",
74
+ $borderRadiusX: 1.25,
75
+ $gutterX: 0.35,
76
+ $gapX: 0.35,
77
+ $flexGapX: 0.25,
78
+ children: [
79
+ /* @__PURE__ */ e(m, { $renderAs: "ac3-black", children: n <= i.LAST_FIVE ? `0${M / 60}:00` : `${z / 60}:00` }),
80
+ /* @__PURE__ */ e(m, { $renderAs: "ac3-black", children: "Left" })
81
+ ]
82
+ }
83
+ )
84
+ }
85
+ ),
86
+ h && /* @__PURE__ */ e(V, { children: /* @__PURE__ */ e(
87
+ I,
88
+ {
89
+ onAnimationComplete: L,
90
+ background: "BLACK",
91
+ Icon: /* @__PURE__ */ e(D, { label: "Extend Class", onClick: C, children: /* @__PURE__ */ e(a, { $background: "WHITE", $borderRadiusX: 1.25, $borderColor: "BLACK_3", children: /* @__PURE__ */ e(O, { width: 16, height: 16 }) }) }),
92
+ size: 24,
93
+ visible: $,
94
+ idleTime: R,
95
+ children: /* @__PURE__ */ e(W, { $color: "WHITE", $renderAs: "body3", children: "Extend Class" })
96
+ }
97
+ ) })
98
+ ] });
99
+ }, Z = N(j);
100
+ export {
101
+ Z as default
102
+ };
103
+ //# sourceMappingURL=animate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animate.js","sources":["../../../src/features/class-timer/animate.tsx"],"sourcesContent":["import { useState, useCallback, useEffect, useRef, memo } from 'react';\nimport styled from 'styled-components';\n\nimport PlusIcon from '../../assets/line-icons/icons/plus';\nimport usePrevious from '../hooks/use-previous';\nimport Clickable from '../ui/buttons/clickable/clickable';\nimport FlexView from '../ui/layout/flex-view';\nimport Text from '../ui/text/text';\nimport OpenCloseAnimation from './animations/open-close';\nimport { ANIMATION_TIME, EXTEND_IDLE, LAST_FIVE, START_TIMER, TIME_LEFT_IDLE } from './constants';\n\nconst IconWrapper = styled(FlexView)`\n position: absolute;\n top: -8px;\n right: 8px;\n z-index: ${({ theme }) => theme.zIndex.EXTEND_CLASS_ANIMATION_3};\n`;\n\nconst StyledText = styled(Text)`\n padding-left: 4px;\n padding-right: 8px;\n`;\n\nconst NoWrapRow = styled(FlexView)`\n flex-flow: nowrap;\n z-index: ${({ theme }) => theme.zIndex.EXTEND_CLASS_ANIMATION_2};\n`;\n\nconst OpacityWrapper = styled(FlexView)`\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: ${({ theme }) => theme.zIndex.EXTEND_CLASS_ANIMATION_1};\n`;\n\ninterface AnimateProps {\n animateClock: boolean;\n classStartedTime: number;\n duration: number;\n onAnimation?: () => void;\n onExtendClass?: () => void;\n setAnimateClock: (value: boolean) => void;\n setStartTimer: (value: boolean) => void;\n showExtendIcon?: boolean;\n}\n\nconst Animate = (props: AnimateProps) => {\n const {\n animateClock,\n classStartedTime,\n duration,\n onAnimation = () => {},\n onExtendClass = () => {},\n setAnimateClock,\n setStartTimer,\n showExtendIcon = false,\n } = props;\n const [animateTip, setAnimateTip] = useState(false);\n const remainingTime = Math.floor(duration - (+new Date() - classStartedTime) / 1000); // in seconds\n const showIcon = showExtendIcon && remainingTime <= ANIMATION_TIME.LAST_FIVE;\n const previousAnimateClock = usePrevious(animateClock);\n const timer = useRef<NodeJS.Timeout | null>(null);\n\n useEffect(() => {\n if (animateClock && !previousAnimateClock) {\n timer.current = setTimeout(() => {\n setAnimateTip(true);\n }, 1000);\n }\n }, [animateClock, previousAnimateClock]);\n\n useEffect(() => {\n return () => {\n if (timer.current) {\n clearTimeout(timer.current);\n }\n };\n }, []);\n\n const onClockAnimationComplete = useCallback(() => {\n setAnimateClock(false);\n }, [setAnimateClock]);\n\n const onOpenAnimationComplete = useCallback(() => {\n setStartTimer(true);\n onAnimation();\n }, [onAnimation, setStartTimer]);\n\n const onAnimateComplete = useCallback(() => {\n setAnimateTip(false);\n }, [setAnimateTip]);\n\n return (\n <>\n {remainingTime <= ANIMATION_TIME.LAST_FIVE && animateClock && <OpacityWrapper />}\n <OpenCloseAnimation\n background={remainingTime <= ANIMATION_TIME.LAST_FIVE ? 'ORANGE_4' : 'YELLOW_3'}\n onAnimationComplete={onClockAnimationComplete}\n onOpenAnimationComplete={onOpenAnimationComplete}\n visible={animateClock}\n idleTime={TIME_LEFT_IDLE}\n >\n <NoWrapRow\n $flexDirection=\"row\"\n $alignItems=\"center\"\n $width=\"100%\"\n $justifyContent=\"space-around\"\n $borderRadiusX={1.25}\n $gutterX={0.35}\n $gapX={0.35}\n $flexGapX={0.25}\n >\n <Text $renderAs=\"ac3-black\">\n {remainingTime <= ANIMATION_TIME.LAST_FIVE\n ? `0${LAST_FIVE / 60}:00`\n : `${START_TIMER / 60}:00`}\n </Text>\n <Text $renderAs=\"ac3-black\">Left</Text>\n </NoWrapRow>\n </OpenCloseAnimation>\n {showIcon && (\n <IconWrapper>\n <OpenCloseAnimation\n onAnimationComplete={onAnimateComplete}\n background=\"BLACK\"\n Icon={\n <Clickable label=\"Extend Class\" onClick={onExtendClass}>\n <FlexView $background=\"WHITE\" $borderRadiusX={1.25} $borderColor=\"BLACK_3\">\n <PlusIcon width={16} height={16} />\n </FlexView>\n </Clickable>\n }\n size={24}\n visible={animateTip}\n idleTime={EXTEND_IDLE}\n >\n <StyledText $color=\"WHITE\" $renderAs=\"body3\">\n Extend Class\n </StyledText>\n </OpenCloseAnimation>\n </IconWrapper>\n )}\n </>\n );\n};\n\nexport default memo(Animate);\n"],"names":["IconWrapper","styled","FlexView","theme","StyledText","Text","NoWrapRow","OpacityWrapper","Animate","props","animateClock","classStartedTime","duration","onAnimation","onExtendClass","setAnimateClock","setStartTimer","showExtendIcon","animateTip","setAnimateTip","useState","remainingTime","showIcon","ANIMATION_TIME","previousAnimateClock","usePrevious","timer","useRef","useEffect","onClockAnimationComplete","useCallback","onOpenAnimationComplete","onAnimateComplete","jsxs","Fragment","jsx","OpenCloseAnimation","TIME_LEFT_IDLE","LAST_FIVE","START_TIMER","Clickable","PlusIcon","EXTEND_IDLE","Animate$1","memo"],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ import { jsxs as g, jsx as $ } from "react/jsx-runtime";
2
+ import { memo as A, useState as y, useRef as E, useEffect as s } from "react";
3
+ import c, { keyframes as h, css as m } from "styled-components";
4
+ import x from "../../ui/layout/flex-view.js";
5
+ const X = h`
6
+ 0% {
7
+ transform: translateX(-100%);
8
+ }
9
+ 100% {
10
+ transform: translateX(0%);
11
+ }
12
+ `, M = h`
13
+ 0% {
14
+ transform: translateX(0%);
15
+ }
16
+ 100% {
17
+ transform: translateX(-100%);
18
+ }
19
+ `, l = 1 * 1e3, R = 1.5 * 1e3, b = c(x)`
20
+ position: absolute;
21
+ z-index: 10;
22
+ overflow: hidden;
23
+ `, j = c.div`
24
+ position: absolute;
25
+ cursor: pointer;
26
+ z-index: 1;
27
+ `, k = c(x)`
28
+ animation-name: ${({ $animate: t }) => t ? X : M};
29
+ max-width: fit-content;
30
+ animation-duration: ${l / 1e3}s;
31
+ animation-timing-function: ease-in-out;
32
+ animation-fill-mode: forwards;
33
+ overflow: hidden;
34
+ white-space: nowrap;
35
+ height: 100%;
36
+ ${({ width: t }) => t && m`
37
+ max-width: ${t};
38
+ width: ${t};
39
+ `};
40
+ ${({ isIcon: t, size: r }) => t && m`
41
+ padding-left: ${r}px;
42
+ `};
43
+ ${({ isVisible: t }) => !t && m`
44
+ visibility: hidden;
45
+ `};
46
+ `, z = ({
47
+ background: t,
48
+ borderRadius: r = 16,
49
+ children: w,
50
+ Icon: i = null,
51
+ onAnimationComplete: f = () => {
52
+ },
53
+ onOpenAnimationComplete: u = () => {
54
+ },
55
+ size: T = null,
56
+ visible: e,
57
+ width: I = null,
58
+ idleTime: d = R
59
+ }) => {
60
+ const [n, p] = y(!1), o = E(!1);
61
+ return s(() => {
62
+ e && (o.current = !1, p(!0));
63
+ }, [e]), s(() => {
64
+ if (n) {
65
+ const a = setTimeout(() => {
66
+ o.current = !0, p(!1), u();
67
+ }, l + d);
68
+ return () => {
69
+ clearTimeout(a);
70
+ };
71
+ }
72
+ }, [n, u, d]), s(() => {
73
+ if (e && !n && o.current) {
74
+ const a = setTimeout(() => {
75
+ f();
76
+ }, l);
77
+ return () => {
78
+ clearTimeout(a);
79
+ };
80
+ }
81
+ }, [e, n, f]), /* @__PURE__ */ g(b, { $flexDirection: "row", $alignItems: "center", $borderRadius: r, children: [
82
+ i && /* @__PURE__ */ $(j, { children: i }),
83
+ /* @__PURE__ */ $(
84
+ k,
85
+ {
86
+ $alignItems: "center",
87
+ $animate: n,
88
+ $background: t,
89
+ $borderRadius: r,
90
+ isIcon: !!i,
91
+ isVisible: e,
92
+ size: T,
93
+ width: I,
94
+ children: w
95
+ }
96
+ )
97
+ ] });
98
+ }, S = A(z);
99
+ export {
100
+ S as default
101
+ };
102
+ //# sourceMappingURL=open-close.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-close.js","sources":["../../../../src/features/class-timer/animations/open-close.tsx"],"sourcesContent":["import type { TColorNames } from '../../ui/types';\n\nimport React, { useState, useEffect, useRef, memo } from 'react';\nimport styled, { css, keyframes } from 'styled-components';\n\nimport FlexView from '../../ui/layout/flex-view';\n\nconst FillAnimation = keyframes`\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(0%);\n }\n`;\n\nconst EmptyAnimation = keyframes`\n 0% {\n transform: translateX(0%);\n }\n 100% {\n transform: translateX(-100%);\n }\n`;\n\nconst ANIMATION_TIME = 1 * 1000; // 1 seconds\nconst IDLE_TIME = 1.5 * 1000;\n\nconst StyledRow = styled(FlexView)`\n position: absolute;\n z-index: 10;\n overflow: hidden;\n`;\n\nconst IconWrapper = styled.div`\n position: absolute;\n cursor: pointer;\n z-index: 1;\n`;\n\nconst Wrapper = styled(FlexView)<{\n $animate: boolean;\n isIcon: boolean;\n isVisible: boolean;\n size: number | null;\n width: string | number | null;\n}>`\n animation-name: ${({ $animate }) => ($animate ? FillAnimation : EmptyAnimation)};\n max-width: fit-content;\n animation-duration: ${ANIMATION_TIME / 1000}s;\n animation-timing-function: ease-in-out;\n animation-fill-mode: forwards;\n overflow: hidden;\n white-space: nowrap;\n height: 100%;\n ${({ width }) =>\n width &&\n css`\n max-width: ${width};\n width: ${width};\n `};\n ${({ isIcon, size }) =>\n isIcon &&\n css`\n padding-left: ${size}px;\n `};\n ${({ isVisible }) =>\n !isVisible &&\n css`\n visibility: hidden;\n `};\n`;\n\ninterface OpenCloseAnimationProps {\n background: TColorNames;\n children: React.ReactNode;\n onAnimationComplete?: () => void;\n onOpenAnimationComplete?: () => void;\n visible: boolean;\n height?: string | number;\n Icon?: React.ReactNode;\n borderRadius?: number;\n size?: number | null;\n width?: string | number | null;\n idleTime?: number;\n}\n\nconst OpenCloseAnimation: React.FC<OpenCloseAnimationProps> = ({\n background,\n borderRadius = 16,\n children,\n Icon = null,\n onAnimationComplete = () => {},\n onOpenAnimationComplete = () => {},\n size = null,\n visible,\n width = null,\n idleTime = IDLE_TIME,\n}) => {\n const [animate, setAnimate] = useState(false);\n const prevAnimate = useRef(false);\n\n useEffect(() => {\n if (visible) {\n prevAnimate.current = false;\n setAnimate(true);\n }\n }, [visible]);\n\n useEffect(() => {\n if (animate) {\n const animateTimer = setTimeout(() => {\n prevAnimate.current = true;\n setAnimate(false);\n onOpenAnimationComplete();\n }, ANIMATION_TIME + idleTime);\n\n return () => {\n clearTimeout(animateTimer);\n };\n }\n }, [animate, onOpenAnimationComplete, idleTime]);\n\n useEffect(() => {\n if (visible && !animate && prevAnimate.current) {\n const hideTimer = setTimeout(() => {\n onAnimationComplete();\n }, ANIMATION_TIME);\n\n return () => {\n clearTimeout(hideTimer);\n };\n }\n }, [visible, animate, onAnimationComplete]);\n\n return (\n <StyledRow $flexDirection=\"row\" $alignItems=\"center\" $borderRadius={borderRadius}>\n {Icon && <IconWrapper>{Icon}</IconWrapper>}\n <Wrapper\n $alignItems=\"center\"\n $animate={animate}\n $background={background}\n $borderRadius={borderRadius}\n isIcon={!!Icon}\n isVisible={visible}\n size={size}\n width={width}\n >\n {children}\n </Wrapper>\n </StyledRow>\n );\n};\n\nexport default memo(OpenCloseAnimation);\n"],"names":["FillAnimation","keyframes","EmptyAnimation","ANIMATION_TIME","IDLE_TIME","StyledRow","styled","FlexView","IconWrapper","Wrapper","$animate","width","css","isIcon","size","isVisible","OpenCloseAnimation","background","borderRadius","children","Icon","onAnimationComplete","onOpenAnimationComplete","visible","idleTime","animate","setAnimate","useState","prevAnimate","useRef","useEffect","animateTimer","hideTimer","jsx","OpenCloseAnimation$1","memo"],"mappings":";;;;AAOA,MAAMA,IAAgBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAShBC,IAAiBD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASjBE,IAAiB,IAAI,KACrBC,IAAY,MAAM,KAElBC,IAAYC,EAAOC,CAAQ;AAAA;AAAA;AAAA;AAAA,GAM3BC,IAAcF,EAAO;AAAA;AAAA;AAAA;AAAA,GAMrBG,IAAUH,EAAOC,CAAQ;AAAA,oBAOX,CAAC,EAAE,UAAAG,EAAA,MAAgBA,IAAWV,IAAgBE,CAAe;AAAA;AAAA,wBAEzDC,IAAiB,GAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMzC,CAAC,EAAE,OAAAQ,QACHA,KACAC;AAAA,mBACeD,CAAK;AAAA,eACTA,CAAK;AAAA,KACf;AAAA,IACD,CAAC,EAAE,QAAAE,GAAQ,MAAAC,EAAA,MACXD,KACAD;AAAA,sBACkBE,CAAI;AAAA,KACrB;AAAA,IACD,CAAC,EAAE,WAAAC,EAAU,MACb,CAACA,KACDH;AAAA;AAAA,KAEC;AAAA,GAiBCI,IAAwD,CAAC;AAAA,EAC7D,YAAAC;AAAA,EACA,cAAAC,IAAe;AAAA,EACf,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,qBAAAC,IAAsB,MAAM;AAAA,EAAC;AAAA,EAC7B,yBAAAC,IAA0B,MAAM;AAAA,EAAC;AAAA,EACjC,MAAAR,IAAO;AAAA,EACP,SAAAS;AAAA,EACA,OAAAZ,IAAQ;AAAA,EACR,UAAAa,IAAWpB;AACb,MAAM;AACJ,QAAM,CAACqB,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtCC,IAAcC,EAAO,EAAK;AAEhC,SAAAC,EAAU,MAAM;AACd,IAAIP,MACFK,EAAY,UAAU,IACtBF,EAAW,EAAI;AAAA,EACjB,GACC,CAACH,CAAO,CAAC,GAEZO,EAAU,MAAM;AACd,QAAIL,GAAS;AACL,YAAAM,IAAe,WAAW,MAAM;AACpC,QAAAH,EAAY,UAAU,IACtBF,EAAW,EAAK,GACQJ;MAAA,GACvBnB,IAAiBqB,CAAQ;AAE5B,aAAO,MAAM;AACX,qBAAaO,CAAY;AAAA,MAAA;AAAA,IAE7B;AAAA,EACC,GAAA,CAACN,GAASH,GAAyBE,CAAQ,CAAC,GAE/CM,EAAU,MAAM;AACd,QAAIP,KAAW,CAACE,KAAWG,EAAY,SAAS;AACxC,YAAAI,IAAY,WAAW,MAAM;AACb,QAAAX;SACnBlB,CAAc;AAEjB,aAAO,MAAM;AACX,qBAAa6B,CAAS;AAAA,MAAA;AAAA,IAE1B;AAAA,EACC,GAAA,CAACT,GAASE,GAASJ,CAAmB,CAAC,qBAGvChB,GAAU,EAAA,gBAAe,OAAM,aAAY,UAAS,eAAea,GACjE,UAAA;AAAA,IAAQE,KAAA,gBAAAa,EAACzB,KAAa,UAAKY,EAAA,CAAA;AAAA,IAC5B,gBAAAa;AAAA,MAACxB;AAAA,MAAA;AAAA,QACC,aAAY;AAAA,QACZ,UAAUgB;AAAA,QACV,aAAaR;AAAA,QACb,eAAeC;AAAA,QACf,QAAQ,CAAC,CAACE;AAAA,QACV,WAAWG;AAAA,QACX,MAAAT;AAAA,QACA,OAAAH;AAAA,QAEC,UAAAQ;AAAA,MAAA;AAAA,IACH;AAAA,EACF,EAAA,CAAA;AAEJ,GAEee,IAAAC,EAAKnB,CAAkB;"}
@@ -0,0 +1,44 @@
1
+ import { jsx as r } from "react/jsx-runtime";
2
+ import { memo as a } from "react";
3
+ import p, { css as $, keyframes as m } from "styled-components";
4
+ import x from "../../ui/layout/flex-view.js";
5
+ import { getTheme as d } from "../../ui/theme/get-theme.js";
6
+ const f = d(), { colors: l } = f, u = (e) => {
7
+ const t = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);
8
+ return t && t[1] && t[2] && t[3] ? [parseInt(t[1], 16), parseInt(t[2], 16), parseInt(t[3], 16)] : null;
9
+ }, s = (e, t) => {
10
+ const n = u(e);
11
+ return n ? `rgba(${n.join(", ")}, ${t})` : null;
12
+ }, c = (e) => m`
13
+ 0% {
14
+ box-shadow:
15
+ 0 2px 5px ${e},
16
+ 0 0 0 0 ${e},
17
+ 0 0 0 2px ${s(e, 0.5)},
18
+ 0 0 0 5px ${s(e, 0.5)};
19
+ }
20
+ 100% {
21
+ box-shadow:
22
+ 0 2px 5px ${s(e, 0.5)},
23
+ 0 0 0 2px ${s(e, 0.5)},
24
+ 0 0 0 5px ${s(e, 0.5)},
25
+ 0 0 0 10px ${s(e, 0)};
26
+ }
27
+ `, b = p.div`
28
+ ${({ $visible: e, $borderRadius: t, $color: n }) => e && $`
29
+ animation: ${c(n)} 1s linear infinite;
30
+ background: transparent;
31
+ border-radius: ${t}px;
32
+ z-index: 1;
33
+ `};
34
+ `, g = ({
35
+ children: e,
36
+ visible: t = !1,
37
+ color: n = "YELLOW_1",
38
+ borderRadius: i = 24,
39
+ ...o
40
+ }) => /* @__PURE__ */ r(x, { $position: "relative", $alignItems: "center", $justifyContent: "center", children: /* @__PURE__ */ r(b, { $visible: t, $color: l[n], $borderRadius: i, ...o, children: e }) }), w = a(g);
41
+ export {
42
+ w as default
43
+ };
44
+ //# sourceMappingURL=ripple.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ripple.js","sources":["../../../../src/features/class-timer/animations/ripple.tsx"],"sourcesContent":["import type { TColorNames } from '../../ui/types';\n\nimport { memo, type ReactNode } from 'react';\nimport styled, { keyframes, css } from 'styled-components';\n\nimport FlexView from '../../ui/layout/flex-view';\nimport { getTheme } from '../../ui/theme/get-theme';\n\nconst theme = getTheme();\nconst { colors: COLORS } = theme;\n\nconst toRGB = (hex: string): number[] | null => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n\n return result && result[1] && result[2] && result[3]\n ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)]\n : null;\n};\n\nconst toRGBA = (hex: string, alpha: number): string | null => {\n const rgb = toRGB(hex);\n\n return rgb ? `rgba(${rgb.join(', ')}, ${alpha})` : null;\n};\n\nconst pulse = (color: string) => keyframes`\n 0% {\n box-shadow: \n 0 2px 5px ${color},\n 0 0 0 0 ${color},\n 0 0 0 2px ${toRGBA(color, 0.5)},\n 0 0 0 5px ${toRGBA(color, 0.5)};\n }\n 100% {\n box-shadow:\n 0 2px 5px ${toRGBA(color, 0.5)},\n 0 0 0 2px ${toRGBA(color, 0.5)},\n 0 0 0 5px ${toRGBA(color, 0.5)},\n 0 0 0 10px ${toRGBA(color, 0)};\n }\n`;\n\ninterface PulseProps {\n $visible: boolean;\n $borderRadius: number;\n $color: string;\n}\n\nconst Pulse = styled.div<PulseProps>`\n ${({ $visible, $borderRadius, $color }) =>\n $visible &&\n css`\n animation: ${pulse($color)} 1s linear infinite;\n background: transparent;\n border-radius: ${$borderRadius}px;\n z-index: 1;\n `};\n`;\n\ninterface PulsatingProps {\n children: ReactNode;\n visible?: boolean;\n color?: TColorNames;\n borderRadius?: number;\n}\n\nconst Pulsating = ({\n children,\n visible = false,\n color = 'YELLOW_1',\n borderRadius = 24,\n ...other\n}: PulsatingProps) => (\n <FlexView $position=\"relative\" $alignItems=\"center\" $justifyContent=\"center\">\n <Pulse $visible={visible} $color={COLORS[color]} $borderRadius={borderRadius} {...other}>\n {children}\n </Pulse>\n </FlexView>\n);\n\nexport default memo(Pulsating);\n"],"names":["theme","getTheme","COLORS","toRGB","hex","result","toRGBA","alpha","rgb","pulse","color","keyframes","Pulse","styled","$visible","$borderRadius","$color","css","Pulsating","children","visible","borderRadius","other","jsx","FlexView","Ripple","memo"],"mappings":";;;;;AAQA,MAAMA,IAAQC,EAAS,GACjB,EAAE,QAAQC,EAAW,IAAAF,GAErBG,IAAQ,CAACC,MAAiC;AACxC,QAAAC,IAAS,4CAA4C,KAAKD,CAAG;AAEnE,SAAOC,KAAUA,EAAO,CAAC,KAAKA,EAAO,CAAC,KAAKA,EAAO,CAAC,IAC/C,CAAC,SAASA,EAAO,CAAC,GAAG,EAAE,GAAG,SAASA,EAAO,CAAC,GAAG,EAAE,GAAG,SAASA,EAAO,CAAC,GAAG,EAAE,CAAC,IAC1E;AACN,GAEMC,IAAS,CAACF,GAAaG,MAAiC;AACtD,QAAAC,IAAML,EAAMC,CAAG;AAEd,SAAAI,IAAM,QAAQA,EAAI,KAAK,IAAI,CAAC,KAAKD,CAAK,MAAM;AACrD,GAEME,IAAQ,CAACC,MAAkBC;AAAA;AAAA;AAAA,kBAGfD,CAAK;AAAA,gBACPA,CAAK;AAAA,kBACHJ,EAAOI,GAAO,GAAG,CAAC;AAAA,kBAClBJ,EAAOI,GAAO,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA,kBAIlBJ,EAAOI,GAAO,GAAG,CAAC;AAAA,kBAClBJ,EAAOI,GAAO,GAAG,CAAC;AAAA,kBAClBJ,EAAOI,GAAO,GAAG,CAAC;AAAA,mBACjBJ,EAAOI,GAAO,CAAC,CAAC;AAAA;AAAA,GAU7BE,IAAQC,EAAO;AAAA,IACjB,CAAC,EAAE,UAAAC,GAAU,eAAAC,GAAe,QAAAC,QAC5BF,KACAG;AAAA,mBACeR,EAAMO,CAAM,CAAC;AAAA;AAAA,uBAETD,CAAa;AAAA;AAAA,KAE/B;AAAA,GAUCG,IAAY,CAAC;AAAA,EACjB,UAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,OAAAV,IAAQ;AAAA,EACR,cAAAW,IAAe;AAAA,EACf,GAAGC;AACL,MACE,gBAAAC,EAACC,KAAS,WAAU,YAAW,aAAY,UAAS,iBAAgB,UAClE,UAAC,gBAAAD,EAAAX,GAAA,EAAM,UAAUQ,GAAS,QAAQlB,EAAOQ,CAAK,GAAG,eAAeW,GAAe,GAAGC,GAC/E,UAAAH,EACH,CAAA,EACF,CAAA,GAGaM,IAAAC,EAAKR,CAAS;"}
@@ -0,0 +1,155 @@
1
+ import { jsx as c, jsxs as v } from "react/jsx-runtime";
2
+ import { memo as H, useMemo as d, useState as S, useCallback as C, useEffect as x, useRef as J } from "react";
3
+ import K from "../../assets/line-icons/icons/clock2.js";
4
+ import Q from "../hooks/use-visibility-change.js";
5
+ import k from "../ui/layout/flex-view.js";
6
+ import U from "./animate.js";
7
+ import Z from "./animations/ripple.js";
8
+ import ee from "./clock.js";
9
+ import { START_TIMER as te, getClockColor as ne, ANIMATION_TIME as R, LAST_FIVE as re, IconWrapper as ie } from "./constants.js";
10
+ import oe from "./timer.js";
11
+ const se = (O) => {
12
+ const {
13
+ backgroundColor: V = "GREY_1",
14
+ onAnimation: X = () => {
15
+ },
16
+ onComplete: p = () => {
17
+ },
18
+ onExtendClass: G = () => {
19
+ },
20
+ onExtendedTimeStart: A = () => {
21
+ },
22
+ showExtendIcon: W = !1,
23
+ status: j = null,
24
+ updateWithExtendedTime: l = !0,
25
+ multiReminders: E = []
26
+ } = O, {
27
+ class_duration: t = 0,
28
+ classStartedTime: r = 0,
29
+ extended_time: n = 0,
30
+ ongoing: P
31
+ } = j || {}, u = (+/* @__PURE__ */ new Date() - +r) / 1e3, m = Q(), I = d(() => n ? Math.floor(t - u) <= n * 60 : !1, [t, n, u]), [s, Y] = S(I), f = d(() => {
32
+ const e = (+/* @__PURE__ */ new Date() - +r) / 1e3, o = Math.floor(t - e);
33
+ return l || !n || o <= n * 60 ? t : t - n * 60;
34
+ }, [t, n, r, l]), [a, w] = S(f), b = d(() => a + +r / 1e3, [a, r]), $ = d(() => !!(u >= a - te || s || l && n), [u, a, s, l, n]), [_, D] = S(!1), T = Math.floor(a - u), [M, y] = S($), q = ne({
35
+ remainingTime: T,
36
+ updateWithExtendedTime: l,
37
+ extendedTime: n,
38
+ extendedTimeStarted: s
39
+ }), h = C(() => {
40
+ Y(!0), w(f), A();
41
+ }, [f, A]), g = C(() => {
42
+ D(!0);
43
+ }, []), L = d(
44
+ () => [
45
+ {
46
+ at: R.LAST_TEN,
47
+ callback: g,
48
+ id: "rem-10min",
49
+ persist: !1
50
+ },
51
+ {
52
+ at: R.LAST_FIVE,
53
+ callback: g,
54
+ id: "rem-5min",
55
+ persist: !1
56
+ }
57
+ ],
58
+ [g]
59
+ ), F = d(() => {
60
+ const e = new Set(E.map((o) => o.id));
61
+ return [...L.filter((o) => !e.has(o.id)), ...E];
62
+ }, [L, E]), z = C(() => {
63
+ if (n && !s && !l) {
64
+ h();
65
+ return;
66
+ }
67
+ p();
68
+ }, [
69
+ n,
70
+ s,
71
+ p,
72
+ h,
73
+ l
74
+ ]);
75
+ x(() => {
76
+ const e = +/* @__PURE__ */ new Date() / 1e3 >= +r / 1e3 + t && t;
77
+ m && e && p();
78
+ }, [t, r, m, p]), x(() => {
79
+ t && w(f);
80
+ }, [t, f]), x(() => {
81
+ m && I && !s && h();
82
+ }, [m, h, s, I]), x(() => {
83
+ a && r && m && y($);
84
+ }, [r, a, $, m]);
85
+ const N = J(/* @__PURE__ */ new Set()), i = d(
86
+ () => F.filter((e) => {
87
+ const o = e.id || `multi-reminder-${e.at}`;
88
+ return !(!!e.persist ? localStorage.getItem(o) === "true" : N.current.has(o)) && T >= e.at;
89
+ }).sort((e, o) => o.at - e.at)[0],
90
+ [F, T]
91
+ ), B = C(() => {
92
+ if (!i) return;
93
+ const e = i.id || `multi-reminder-${i.at}`;
94
+ i.persist ? localStorage.setItem(e, "true") : N.current.add(e), typeof i.callback == "function" && i.callback();
95
+ }, [i]);
96
+ return !P || u >= 0 && T <= 0 ? null : /* @__PURE__ */ c(k, { $flexDirection: "row", $alignItems: "center", children: /* @__PURE__ */ v(k, { $position: "relative", $flexDirection: "row", $alignItems: "center", children: [
97
+ /* @__PURE__ */ c(
98
+ U,
99
+ {
100
+ animateClock: _,
101
+ classStartedTime: +r,
102
+ duration: a,
103
+ onAnimation: X,
104
+ onExtendClass: G,
105
+ setAnimateClock: D,
106
+ setStartTimer: y,
107
+ showExtendIcon: !s && W
108
+ }
109
+ ),
110
+ /* @__PURE__ */ c(
111
+ Z,
112
+ {
113
+ color: T <= re ? "ORANGE_3" : "YELLOW_3",
114
+ visible: !_ && M,
115
+ children: /* @__PURE__ */ v(
116
+ k,
117
+ {
118
+ $flexDirection: "row",
119
+ $alignItems: "center",
120
+ $background: V,
121
+ $borderRadiusX: 1.25,
122
+ $gutterX: 0.5,
123
+ $gapX: 0.25,
124
+ $flexGapX: 0.25,
125
+ $position: "relative",
126
+ children: [
127
+ /* @__PURE__ */ c(ie, { $iconColor: q, children: /* @__PURE__ */ c(K, {}) }),
128
+ m && (M ? /* @__PURE__ */ c(
129
+ oe,
130
+ {
131
+ endTime: b,
132
+ onComplete: z,
133
+ reminder: i == null ? void 0 : i.at,
134
+ onReminder: B
135
+ },
136
+ b
137
+ ) : /* @__PURE__ */ c(
138
+ ee,
139
+ {
140
+ completionTime: t - R.LAST_TEN,
141
+ onComplete: g,
142
+ startedOn: new Date(r)
143
+ }
144
+ ))
145
+ ]
146
+ }
147
+ )
148
+ }
149
+ )
150
+ ] }) });
151
+ }, Ce = H(se);
152
+ export {
153
+ Ce as default
154
+ };
155
+ //# sourceMappingURL=class-timer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-timer.js","sources":["../../../src/features/class-timer/class-timer.tsx"],"sourcesContent":["import type { TColorNames } from '../ui/types';\n\nimport { useState, useCallback, useEffect, useMemo, useRef, memo } from 'react';\n\nimport Clock2Icon from '../../assets/line-icons/icons/clock2';\nimport useVisibilityChange from '../hooks/use-visibility-change';\nimport FlexView from '../ui/layout/flex-view';\nimport Animate from './animate';\nimport Ripple from './animations/ripple';\nimport Clock from './clock';\nimport { ANIMATION_TIME, getClockColor, IconWrapper, LAST_FIVE, START_TIMER } from './constants';\nimport Timer from './timer';\n\nexport interface MultiReminder {\n at: number;\n callback: () => void;\n id?: string;\n persist?: boolean;\n}\n\ninterface IClassTimeProps {\n backgroundColor?: TColorNames;\n onAnimation?: () => void;\n onComplete?: () => void;\n onExtendClass?: () => void;\n onExtendedTimeStart?: () => void;\n onTMinusOne?: () => void;\n showExtendIcon?: boolean;\n showExtendText?: boolean;\n status?: {\n class_duration: number;\n classStartedTime: Date;\n extended_time: number;\n ongoing: boolean;\n } | null;\n updateWithExtendedTime?: boolean;\n multiReminders: MultiReminder[]; // new, supports per-mount and per-session\n}\n\nconst ClassTime = (props: IClassTimeProps) => {\n const {\n backgroundColor = 'GREY_1',\n onAnimation = () => {},\n onComplete = () => {},\n onExtendClass = () => {},\n onExtendedTimeStart = () => {},\n showExtendIcon = false,\n status = null,\n updateWithExtendedTime = true,\n multiReminders = [],\n } = props;\n\n const {\n class_duration: classDuration = 0,\n classStartedTime = 0,\n extended_time: extendedTime = 0,\n ongoing,\n } = status || {};\n const elapsedTime = (+new Date() - +classStartedTime) / 1000;\n const isTabActive = useVisibilityChange();\n\n const hasExtendedTimeStarted = useMemo(() => {\n if (!extendedTime) return false;\n\n const orgRemainingTime = Math.floor(classDuration - elapsedTime);\n\n return orgRemainingTime <= extendedTime * 60;\n }, [classDuration, extendedTime, elapsedTime]);\n\n const [extendedTimeStarted, setExtendedTimeStarted] = useState(hasExtendedTimeStarted);\n\n const computedDuration = useMemo(() => {\n const elapsedT = (+new Date() - +classStartedTime) / 1000;\n const remainingT = Math.floor(classDuration - elapsedT);\n\n if (updateWithExtendedTime || !extendedTime || remainingT <= extendedTime * 60)\n return classDuration;\n\n return classDuration - extendedTime * 60;\n }, [classDuration, extendedTime, classStartedTime, updateWithExtendedTime]);\n\n const [duration, setDuration] = useState(computedDuration);\n const endTime = useMemo(() => duration + +classStartedTime / 1000, [duration, classStartedTime]);\n\n const canStartTimer = useMemo(() => {\n return !!(\n elapsedTime >= duration - START_TIMER ||\n extendedTimeStarted ||\n (updateWithExtendedTime && extendedTime)\n );\n }, [elapsedTime, duration, extendedTimeStarted, updateWithExtendedTime, extendedTime]);\n\n const [animateClock, setAnimateClock] = useState(false);\n const remainingTime = Math.floor(duration - elapsedTime); // in seconds\n const [startTimer, setStartTimer] = useState(canStartTimer);\n const clockColor = getClockColor({\n remainingTime,\n updateWithExtendedTime,\n extendedTime,\n extendedTimeStarted,\n });\n\n const handleStartExtendedTime = useCallback(() => {\n setExtendedTimeStarted(true);\n setDuration(computedDuration);\n onExtendedTimeStart();\n }, [computedDuration, onExtendedTimeStart]);\n\n const handleStartAnimation = useCallback(() => {\n setAnimateClock(true);\n }, []);\n\n const animationReminders: MultiReminder[] = useMemo(\n () => [\n {\n at: ANIMATION_TIME.LAST_TEN,\n callback: handleStartAnimation,\n id: 'rem-10min',\n persist: false,\n },\n\n {\n at: ANIMATION_TIME.LAST_FIVE,\n callback: handleStartAnimation,\n id: 'rem-5min',\n persist: false,\n },\n ],\n [handleStartAnimation],\n );\n\n const allReminders = useMemo(() => {\n // Avoid duplicate ids if user already provides these\n const userIds = new Set(multiReminders.map(r => r.id));\n\n return [...animationReminders.filter(r => !userIds.has(r.id)), ...multiReminders];\n }, [animationReminders, multiReminders]);\n const handleTimerComplete = useCallback(() => {\n if (extendedTime && !extendedTimeStarted && !updateWithExtendedTime) {\n handleStartExtendedTime();\n\n return;\n }\n onComplete();\n }, [\n extendedTime,\n extendedTimeStarted,\n onComplete,\n handleStartExtendedTime,\n updateWithExtendedTime,\n ]);\n\n useEffect(() => {\n const isClassCompleted =\n +new Date() / 1000 >= +classStartedTime / 1000 + classDuration && classDuration;\n\n if (isTabActive && isClassCompleted) {\n onComplete();\n }\n }, [classDuration, classStartedTime, isTabActive, onComplete]);\n\n useEffect(() => {\n if (classDuration) {\n setDuration(computedDuration);\n }\n }, [classDuration, computedDuration]);\n\n useEffect(() => {\n if (isTabActive && hasExtendedTimeStarted && !extendedTimeStarted) {\n handleStartExtendedTime();\n }\n }, [isTabActive, handleStartExtendedTime, extendedTimeStarted, hasExtendedTimeStarted]);\n\n useEffect(() => {\n if (duration && classStartedTime && isTabActive) {\n setStartTimer(canStartTimer);\n }\n }, [classStartedTime, duration, canStartTimer, isTabActive]);\n\n const firedReminders = useRef<Set<string>>(new Set());\n const nextReminder = useMemo(\n () =>\n allReminders\n .filter((r: MultiReminder) => {\n const key = r.id || `multi-reminder-${r.at}`;\n const shouldPersist = !!r.persist;\n const alreadyFired = shouldPersist\n ? localStorage.getItem(key) === 'true'\n : firedReminders.current.has(key);\n\n return !alreadyFired && remainingTime >= r.at;\n })\n .sort((a: { at: number }, b: { at: number }) => b.at - a.at)[0],\n [allReminders, remainingTime],\n );\n\n const handleMultiReminder = useCallback(() => {\n if (!nextReminder) return;\n\n const key = nextReminder.id || `multi-reminder-${nextReminder.at}`;\n\n if (nextReminder.persist) {\n localStorage.setItem(key, 'true');\n } else {\n firedReminders.current.add(key);\n }\n\n if (typeof nextReminder.callback === 'function') {\n nextReminder.callback();\n }\n }, [nextReminder]);\n\n if (!ongoing || (elapsedTime >= 0 && remainingTime <= 0)) {\n return null;\n }\n\n return (\n <FlexView $flexDirection=\"row\" $alignItems=\"center\">\n <FlexView $position=\"relative\" $flexDirection=\"row\" $alignItems=\"center\">\n <Animate\n animateClock={animateClock}\n classStartedTime={+classStartedTime}\n duration={duration}\n onAnimation={onAnimation}\n onExtendClass={onExtendClass}\n setAnimateClock={setAnimateClock}\n setStartTimer={setStartTimer}\n showExtendIcon={!extendedTimeStarted && showExtendIcon}\n />\n <Ripple\n color={remainingTime <= LAST_FIVE ? 'ORANGE_3' : 'YELLOW_3'}\n visible={!animateClock && startTimer}\n >\n <FlexView\n $flexDirection=\"row\"\n $alignItems=\"center\"\n $background={backgroundColor}\n $borderRadiusX={1.25}\n $gutterX={0.5}\n $gapX={0.25}\n $flexGapX={0.25}\n $position=\"relative\"\n >\n <IconWrapper $iconColor={clockColor}>\n <Clock2Icon />\n </IconWrapper>\n {isTabActive &&\n (startTimer ? (\n <Timer\n endTime={endTime}\n key={endTime}\n onComplete={handleTimerComplete}\n reminder={nextReminder?.at}\n onReminder={handleMultiReminder}\n />\n ) : (\n <Clock\n completionTime={classDuration - ANIMATION_TIME.LAST_TEN}\n onComplete={handleStartAnimation}\n startedOn={new Date(classStartedTime)}\n />\n ))}\n </FlexView>\n </Ripple>\n </FlexView>\n </FlexView>\n );\n};\n\nexport default memo(ClassTime);\n"],"names":["ClassTime","props","backgroundColor","onAnimation","onComplete","onExtendClass","onExtendedTimeStart","showExtendIcon","status","updateWithExtendedTime","multiReminders","classDuration","classStartedTime","extendedTime","ongoing","elapsedTime","isTabActive","useVisibilityChange","hasExtendedTimeStarted","useMemo","extendedTimeStarted","setExtendedTimeStarted","useState","computedDuration","elapsedT","remainingT","duration","setDuration","endTime","canStartTimer","START_TIMER","animateClock","setAnimateClock","remainingTime","startTimer","setStartTimer","clockColor","getClockColor","handleStartExtendedTime","useCallback","handleStartAnimation","animationReminders","ANIMATION_TIME","allReminders","userIds","r","handleTimerComplete","useEffect","isClassCompleted","firedReminders","useRef","nextReminder","key","a","b","handleMultiReminder","jsx","FlexView","jsxs","Animate","Ripple","LAST_FIVE","IconWrapper","Clock2Icon","Timer","Clock","classTimer","memo"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { jsx as d } from "react/jsx-runtime";
2
+ import { memo as w, useState as E, useRef as m, useCallback as $, useEffect as s } from "react";
3
+ import b from "../ui/text/text.js";
4
+ import { formatTimeInHHMMSS as h } from "../utils/utils.js";
5
+ import { getTime as f, TIMEOUT_INTERVAL as i } from "./constants.js";
6
+ const k = ({
7
+ completionTime: t = null,
8
+ onComplete: o = () => {
9
+ },
10
+ startedOn: u,
11
+ textVariant: a = "ab2-bold",
12
+ textColor: p
13
+ }) => {
14
+ const [e, T] = E(f(u)), r = m(null), l = h(e), n = m(null), c = $(() => {
15
+ performance.now() - (n.current || 0) >= 1e3 && (T(f(u)), n.current = performance.now()), r.current = setTimeout(c, i);
16
+ }, [u]);
17
+ return s(() => {
18
+ t && e >= t && e <= t + 5 && (r.current && (clearTimeout(r.current), r.current = null), o());
19
+ }, [t, e, o]), s(() => (r.current && (clearTimeout(r.current), r.current = null), n.current === null && (n.current = performance.now()), r.current = setTimeout(c, i), () => {
20
+ r.current && clearTimeout(r.current);
21
+ }), [c]), e < 0 ? null : /* @__PURE__ */ d(b, { $width: l.length > 5 ? 71 : 57, $renderAs: a, $color: p, children: l });
22
+ }, C = w(k);
23
+ export {
24
+ C as default
25
+ };
26
+ //# sourceMappingURL=clock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.js","sources":["../../../src/features/class-timer/clock.tsx"],"sourcesContent":["import type { TColorNames, TTextVariants } from '../ui/types';\n\nimport { useState, useEffect, useCallback, useRef, memo } from 'react';\n\nimport Text from '../ui/text/text';\nimport { formatTimeInHHMMSS } from '../utils/utils';\nimport { getTime, TIMEOUT_INTERVAL } from './constants';\n\ninterface IClockProps {\n completionTime?: number | null;\n onComplete?: () => void;\n startedOn: Date;\n textVariant?: TTextVariants;\n textColor?: TColorNames;\n}\n\nconst Clock = ({\n completionTime = null,\n onComplete = () => {},\n startedOn,\n textVariant = 'ab2-bold',\n textColor,\n}: IClockProps) => {\n const [elapsedTime, setElapsedTime] = useState(getTime(startedOn));\n const timerRef = useRef<NodeJS.Timeout | null>(null);\n const formattedTime = formatTimeInHHMMSS(elapsedTime);\n const start = useRef<number | null>(null);\n const timer = useCallback(() => {\n const timestamp = performance.now();\n\n const elapsed = timestamp - (start.current || 0);\n\n if (elapsed >= 1000) {\n setElapsedTime(getTime(startedOn));\n\n start.current = performance.now();\n }\n\n timerRef.current = setTimeout(timer, TIMEOUT_INTERVAL);\n }, [startedOn]);\n\n useEffect(() => {\n if (completionTime && elapsedTime >= completionTime && elapsedTime <= completionTime + 5) {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n\n onComplete();\n }\n }, [completionTime, elapsedTime, onComplete]);\n\n useEffect(() => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n\n if (start.current === null) {\n start.current = performance.now();\n }\n\n timerRef.current = setTimeout(timer, TIMEOUT_INTERVAL);\n\n return () => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n }\n };\n }, [timer]);\n\n if (elapsedTime < 0) return null;\n\n return (\n <Text $width={formattedTime.length > 5 ? 71 : 57} $renderAs={textVariant} $color={textColor}>\n {formattedTime}\n </Text>\n );\n};\n\nexport default memo(Clock);\n"],"names":["Clock","completionTime","onComplete","startedOn","textVariant","textColor","elapsedTime","setElapsedTime","useState","getTime","timerRef","useRef","formattedTime","formatTimeInHHMMSS","start","timer","useCallback","TIMEOUT_INTERVAL","useEffect","jsx","Text","Clock$1","memo"],"mappings":";;;;;AAgBA,MAAMA,IAAQ,CAAC;AAAA,EACb,gBAAAC,IAAiB;AAAA,EACjB,YAAAC,IAAa,MAAM;AAAA,EAAC;AAAA,EACpB,WAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,WAAAC;AACF,MAAmB;AACjB,QAAM,CAACC,GAAaC,CAAc,IAAIC,EAASC,EAAQN,CAAS,CAAC,GAC3DO,IAAWC,EAA8B,IAAI,GAC7CC,IAAgBC,EAAmBP,CAAW,GAC9CQ,IAAQH,EAAsB,IAAI,GAClCI,IAAQC,EAAY,MAAM;AAK9B,IAJkB,YAAY,SAEDF,EAAM,WAAW,MAE/B,QACEP,EAAAE,EAAQN,CAAS,CAAC,GAE3BW,EAAA,UAAU,YAAY,QAGrBJ,EAAA,UAAU,WAAWK,GAAOE,CAAgB;AAAA,EAAA,GACpD,CAACd,CAAS,CAAC;AAgCV,SA9BJe,EAAU,MAAM;AACd,IAAIjB,KAAkBK,KAAeL,KAAkBK,KAAeL,IAAiB,MACjFS,EAAS,YACX,aAAaA,EAAS,OAAO,GAC7BA,EAAS,UAAU,OAGVR;EAEZ,GAAA,CAACD,GAAgBK,GAAaJ,CAAU,CAAC,GAE5CgB,EAAU,OACJR,EAAS,YACX,aAAaA,EAAS,OAAO,GAC7BA,EAAS,UAAU,OAGjBI,EAAM,YAAY,SACdA,EAAA,UAAU,YAAY,QAGrBJ,EAAA,UAAU,WAAWK,GAAOE,CAAgB,GAE9C,MAAM;AACX,IAAIP,EAAS,WACX,aAAaA,EAAS,OAAO;AAAA,EAC/B,IAED,CAACK,CAAK,CAAC,GAENT,IAAc,IAAU,OAGzB,gBAAAa,EAAAC,GAAA,EAAK,QAAQR,EAAc,SAAS,IAAI,KAAK,IAAI,WAAWR,GAAa,QAAQC,GAC/E,UACHO,EAAA,CAAA;AAEJ,GAEeS,IAAAC,EAAKtB,CAAK;"}
@@ -0,0 +1,27 @@
1
+ import c from "styled-components";
2
+ import n from "../ui/layout/flex-view.js";
3
+ const s = c(n)`
4
+ svg {
5
+ color: ${(o) => o.theme.colors[o.$iconColor]};
6
+ }
7
+ `, t = 60 * 10, e = 60 * 5, L = {
8
+ LAST_TEN: t + 2,
9
+ LAST_FIVE: e + 2
10
+ }, A = 2e3, l = 1500, i = 250, m = ({
11
+ remainingTime: o,
12
+ updateWithExtendedTime: r,
13
+ extendedTime: T,
14
+ extendedTimeStarted: E
15
+ }) => o <= e ? "ORANGE_3" : o <= t || r && T || E ? "YELLOW_3" : "BLACK_3", M = (o) => Math.floor(((/* @__PURE__ */ new Date()).getTime() - o.getTime()) / 1e3);
16
+ export {
17
+ L as ANIMATION_TIME,
18
+ l as EXTEND_IDLE,
19
+ s as IconWrapper,
20
+ e as LAST_FIVE,
21
+ t as START_TIMER,
22
+ i as TIMEOUT_INTERVAL,
23
+ A as TIME_LEFT_IDLE,
24
+ m as getClockColor,
25
+ M as getTime
26
+ };
27
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../../../src/features/class-timer/constants.ts"],"sourcesContent":["import type { TColorNames } from '../ui/types';\n\nimport styled from 'styled-components';\n\nimport FlexView from '../ui/layout/flex-view';\n\nconst IconWrapper = styled(FlexView)<{ $iconColor: TColorNames }>`\n svg {\n color: ${props => props.theme.colors[props.$iconColor]};\n }\n`;\n\nconst START_TIMER = 60 * 10; // 10 minutes\nconst LAST_FIVE = 60 * 5; // 5 minutes\nconst ANIMATION_TIME = {\n LAST_TEN: START_TIMER + 2,\n LAST_FIVE: LAST_FIVE + 2,\n};\n\nconst TIME_LEFT_IDLE = 2000;\nconst EXTEND_IDLE = 1500;\nconst TIMEOUT_INTERVAL = 250;\n\ninterface IClockColorParams {\n remainingTime: number;\n updateWithExtendedTime: boolean;\n extendedTime: number;\n extendedTimeStarted: boolean;\n}\n\nconst getClockColor = ({\n remainingTime,\n updateWithExtendedTime,\n extendedTime,\n extendedTimeStarted,\n}: IClockColorParams): TColorNames => {\n if (remainingTime <= LAST_FIVE) return 'ORANGE_3';\n\n if (\n remainingTime <= START_TIMER ||\n (updateWithExtendedTime && extendedTime) ||\n extendedTimeStarted\n )\n return 'YELLOW_3';\n\n return 'BLACK_3';\n};\n\nconst getTime = (startedOn: Date): number => {\n return Math.floor((new Date().getTime() - startedOn.getTime()) / 1000);\n};\n\nexport {\n getClockColor,\n getTime,\n IconWrapper,\n ANIMATION_TIME,\n START_TIMER,\n LAST_FIVE,\n TIME_LEFT_IDLE,\n EXTEND_IDLE,\n TIMEOUT_INTERVAL,\n};\n"],"names":["IconWrapper","styled","FlexView","props","START_TIMER","LAST_FIVE","ANIMATION_TIME","TIME_LEFT_IDLE","EXTEND_IDLE","TIMEOUT_INTERVAL","getClockColor","remainingTime","updateWithExtendedTime","extendedTime","extendedTimeStarted","getTime","startedOn"],"mappings":";;AAMM,MAAAA,IAAcC,EAAOC,CAAQ;AAAA;AAAA,aAEtB,OAASC,EAAM,MAAM,OAAOA,EAAM,UAAU,CAAC;AAAA;AAAA,GAIpDC,IAAc,KAAK,IACnBC,IAAY,KAAK,GACjBC,IAAiB;AAAA,EACrB,UAAUF,IAAc;AAAA,EACxB,WAAWC,IAAY;AACzB,GAEME,IAAiB,KACjBC,IAAc,MACdC,IAAmB,KASnBC,IAAgB,CAAC;AAAA,EACrB,eAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,qBAAAC;AACF,MACMH,KAAiBN,IAAkB,aAGrCM,KAAiBP,KAChBQ,KAA0BC,KAC3BC,IAEO,aAEF,WAGHC,IAAU,CAACC,MACR,KAAK,QAAO,oBAAI,KAAK,GAAE,YAAYA,EAAU,QAAQ,KAAK,GAAI;"}