brestok commited on
Commit
cd2dce0
·
1 Parent(s): a1636cc
cbh/api/calls/db_requests.py CHANGED
@@ -54,7 +54,7 @@ async def create_event_obj(
54
  return event
55
 
56
 
57
- async def disable_call(call: CallModel) -> None:
58
  """
59
  Disable a call.
60
  """
@@ -66,11 +66,12 @@ async def disable_call(call: CallModel) -> None:
66
  {"id": call.event.id}, {"$set": {"isActive": False}}
67
  ),
68
  )
 
69
 
70
 
71
  async def enable_call(
72
- call: CallModel, payment_intent_id: str | None, mr_url: str | None
73
- ) -> None:
74
  """
75
  Enable a call.
76
  """
@@ -79,8 +80,13 @@ async def enable_call(
79
  update_data["paymentIntentId"] = payment_intent_id
80
  if mr_url:
81
  update_data["roomUrl"] = mr_url
82
- print(f"Update data: {update_data}")
83
- await settings.DB_CLIENT.calls.update_one({"id": call.id}, {"$set": update_data})
 
 
 
 
 
84
 
85
 
86
  async def cancel_call_obj(call: CallModel) -> CallModel:
 
54
  return event
55
 
56
 
57
+ async def disable_call(call: CallModel) -> CallModel:
58
  """
59
  Disable a call.
60
  """
 
66
  {"id": call.event.id}, {"$set": {"isActive": False}}
67
  ),
68
  )
69
+ return call
70
 
71
 
72
  async def enable_call(
73
+ call: CallModel, payment_intent_id: str, mr_url: str
74
+ ) -> CallModel:
75
  """
76
  Enable a call.
77
  """
 
80
  update_data["paymentIntentId"] = payment_intent_id
81
  if mr_url:
82
  update_data["roomUrl"] = mr_url
83
+ call.status = CallStatus.SCHEDULED
84
+ call.paymentIntentId = payment_intent_id
85
+ call.roomUrl = mr_url
86
+ await settings.DB_CLIENT.calls.update_one(
87
+ {"id": call.id}, {"$set": call.to_mongo()}
88
+ )
89
+ return call
90
 
91
 
92
  async def cancel_call_obj(call: CallModel) -> CallModel:
cbh/api/calls/services/daily.py CHANGED
@@ -11,7 +11,6 @@ async def create_meeting_room(event: EventModel | EventShorten) -> str:
11
  "exp": int(event.endDate.timestamp()) + 3600,
12
  "enable_screenshare": True,
13
  "enable_chat": True,
14
- "nbf": int(event.startDate.timestamp()) - 600,
15
  },
16
  "privacy": "private",
17
  }
 
11
  "exp": int(event.endDate.timestamp()) + 3600,
12
  "enable_screenshare": True,
13
  "enable_chat": True,
 
14
  },
15
  "privacy": "private",
16
  }
cbh/api/calls/services/stripe.py CHANGED
@@ -62,7 +62,7 @@ def verify_stripe_webhook(request: Request, payload: bytes) -> dict:
62
  raise HTTPException(status_code=400, detail="Invalid request")
63
 
64
 
65
- async def manage_stripe_event(event: dict) -> str:
66
  event_type = event["type"]
67
  session = event["data"]["object"]
68
 
@@ -78,13 +78,13 @@ async def manage_stripe_event(event: dict) -> str:
78
  print(f"Payment intent id: {payment_intent_id}")
79
  meeting_room = await create_meeting_room(call.event)
80
  print(f"Meeting room: {meeting_room}")
81
- await enable_call(call, payment_intent_id, meeting_room)
82
 
83
  elif event_type in (
84
  "checkout.session.async_payment_failed",
85
  "checkout.session.expired",
86
  ):
87
- await disable_call(call)
88
 
89
 
90
  async def refund_stripe_payment(payment_intent_id: str) -> None:
 
62
  raise HTTPException(status_code=400, detail="Invalid request")
63
 
64
 
65
+ async def manage_stripe_event(event: dict) -> CallModel:
66
  event_type = event["type"]
67
  session = event["data"]["object"]
68
 
 
78
  print(f"Payment intent id: {payment_intent_id}")
79
  meeting_room = await create_meeting_room(call.event)
80
  print(f"Meeting room: {meeting_room}")
81
+ return await enable_call(call, payment_intent_id, meeting_room)
82
 
83
  elif event_type in (
84
  "checkout.session.async_payment_failed",
85
  "checkout.session.expired",
86
  ):
87
+ return await disable_call(call)
88
 
89
 
90
  async def refund_stripe_payment(payment_intent_id: str) -> None:
cbh/api/calls/utils.py CHANGED
@@ -1,9 +1,12 @@
 
1
  from datetime import datetime, timedelta, timezone
2
 
3
  from fastapi import HTTPException
 
4
 
5
  from cbh.api.calls.models import CallModel
6
  from cbh.api.calls.dto import CallStatus
 
7
 
8
 
9
  def can_edit_call(call: CallModel) -> None:
@@ -13,8 +16,179 @@ def can_edit_call(call: CallModel) -> None:
13
  now = datetime.now(timezone.utc) if call.event.startDate.tzinfo else datetime.now()
14
  min_edit_time = now + timedelta(hours=48)
15
 
16
- if (
17
- call.status != CallStatus.SCHEDULED
18
- or call.event.startDate < min_edit_time
19
- ):
20
- raise HTTPException(status_code=400, detail="Call cannot be edited.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
  from datetime import datetime, timedelta, timezone
3
 
4
  from fastapi import HTTPException
5
+ from jinja2 import Environment, FileSystemLoader, select_autoescape
6
 
7
  from cbh.api.calls.models import CallModel
8
  from cbh.api.calls.dto import CallStatus
9
+ from cbh.core.config import settings
10
 
11
 
12
  def can_edit_call(call: CallModel) -> None:
 
16
  now = datetime.now(timezone.utc) if call.event.startDate.tzinfo else datetime.now()
17
  min_edit_time = now + timedelta(hours=48)
18
 
19
+ if call.status != CallStatus.SCHEDULED or call.event.startDate < min_edit_time:
20
+ raise HTTPException(status_code=400, detail="Call cannot be edited.")
21
+
22
+
23
+ def calculate_sleep_time(call: CallModel) -> int:
24
+ """
25
+ Calculate the sleep time for the reminder.
26
+ """
27
+ now = datetime.now(timezone.utc) if call.event.startDate.tzinfo else datetime.now()
28
+ reminder_time = call.event.startDate - timedelta(hours=1)
29
+ sleep_time = (reminder_time - now).total_seconds()
30
+
31
+ return max(0, int(sleep_time))
32
+
33
+
34
+ async def send_customer_booking_email(call: CallModel) -> None:
35
+ """
36
+ Send a booking email.
37
+ """
38
+ if not call.event.isRecurring:
39
+ return
40
+ templates_path = settings.BASE_DIR / "cbh" / "templates" / "emails"
41
+ env = Environment(
42
+ loader=FileSystemLoader(templates_path),
43
+ autoescape=select_autoescape(["html", "xml"]),
44
+ )
45
+ template = env.get_template("bookingConfirmation.html")
46
+
47
+ template_content = template.render(
48
+ coach_name=call.coach.name,
49
+ user_name=call.customer.name,
50
+ start_date=call.event.startDate.strftime("%d %B %Y, %H:%M"),
51
+ join_link=f"{settings.Audience}/calls/{call.id}",
52
+ duration=(call.event.endDate - call.event.startDate).total_seconds() // 60,
53
+ )
54
+
55
+ await settings.EMAIL_CLIENT.send_email(
56
+ call.customer.email,
57
+ f"You're all set! Session with {call.coach.name} confirmed!",
58
+ template_content,
59
+ )
60
+
61
+
62
+ async def send_coach_booking_email(call: CallModel) -> None:
63
+ """
64
+ Send a booking email.
65
+ """
66
+ if not call.event.isRecurring:
67
+ return
68
+ templates_path = settings.BASE_DIR / "cbh" / "templates" / "emails"
69
+ env = Environment(
70
+ loader=FileSystemLoader(templates_path),
71
+ autoescape=select_autoescape(["html", "xml"]),
72
+ )
73
+ template = env.get_template("bookingConfirmationCoach.html")
74
+ template_content = template.render(
75
+ coach_name=call.coach.name,
76
+ user_name=call.customer.name,
77
+ start_date=call.event.startDate.strftime("%d %B %Y, %H:%M"),
78
+ join_link=f"{settings.Audience}/calls/{call.id}",
79
+ duration=(call.event.endDate - call.event.startDate).total_seconds() // 60,
80
+ )
81
+
82
+ await settings.EMAIL_CLIENT.send_email(
83
+ call.coach.email,
84
+ f"New session booked with {call.customer.name}!",
85
+ template_content,
86
+ )
87
+
88
+
89
+ async def send_cancel_customer_email(call: CallModel) -> None:
90
+ """
91
+ Send a cancellation email.
92
+ """
93
+ templates_path = settings.BASE_DIR / "cbh" / "templates" / "emails"
94
+ env = Environment(
95
+ loader=FileSystemLoader(templates_path),
96
+ autoescape=select_autoescape(["html", "xml"]),
97
+ )
98
+ template = env.get_template("sessionCancellation.html")
99
+ template_content = template.render(
100
+ coach_name=call.coach.name,
101
+ user_name=call.customer.name,
102
+ start_date=call.event.startDate.strftime("%d %B %Y, %H:%M"),
103
+ duration=(call.event.endDate - call.event.startDate).total_seconds() // 60,
104
+ )
105
+
106
+ await settings.EMAIL_CLIENT.send_email(
107
+ call.customer.email,
108
+ f"Your session with {call.coach.name} has been cancelled.",
109
+ template_content,
110
+ )
111
+
112
+
113
+ async def send_cancel_coach_email(call: CallModel) -> None:
114
+ """
115
+ Send a cancellation email.
116
+ """
117
+ templates_path = settings.BASE_DIR / "cbh" / "templates" / "emails"
118
+ env = Environment(
119
+ loader=FileSystemLoader(templates_path),
120
+ autoescape=select_autoescape(["html", "xml"]),
121
+ )
122
+ template = env.get_template("sessionCancellationCoach.html")
123
+ template_content = template.render(
124
+ coach_name=call.coach.name,
125
+ user_name=call.customer.name,
126
+ start_date=call.event.startDate.strftime("%d %B %Y, %H:%M"),
127
+ duration=(call.event.endDate - call.event.startDate).total_seconds() // 60,
128
+ )
129
+
130
+ await settings.EMAIL_CLIENT.send_email(
131
+ call.coach.email,
132
+ f"{call.customer.name} cancelled their session.",
133
+ template_content,
134
+ )
135
+
136
+
137
+ async def send_session_reminder_email(call: CallModel) -> None:
138
+ """
139
+ Send a session reminder email.
140
+ """
141
+ if not call.event.isActive:
142
+ return
143
+ sleep_time = calculate_sleep_time(call)
144
+ await asyncio.sleep(sleep_time)
145
+
146
+ templates_path = settings.BASE_DIR / "cbh" / "templates" / "emails"
147
+ env = Environment(
148
+ loader=FileSystemLoader(templates_path),
149
+ autoescape=select_autoescape(["html", "xml"]),
150
+ )
151
+ template = env.get_template("sessionReminder.html")
152
+ template_content = template.render(
153
+ coach_name=call.coach.name,
154
+ user_name=call.customer.name,
155
+ start_date=call.event.startDate.strftime("%d %B %Y, %H:%M"),
156
+ join_link=f"{settings.Audience}/calls/{call.id}",
157
+ duration=(call.event.endDate - call.event.startDate).total_seconds() // 60,
158
+ )
159
+
160
+ await settings.EMAIL_CLIENT.send_email(
161
+ call.customer.email,
162
+ f"Your session with {call.coach.name} is starting in 1 hour.",
163
+ template_content,
164
+ )
165
+
166
+
167
+ async def send_session_reminder_coach_email(call: CallModel) -> None:
168
+ """
169
+ Send a session reminder email.
170
+ """
171
+ if not call.event.isActive:
172
+ return
173
+ sleep_time = calculate_sleep_time(call)
174
+ await asyncio.sleep(sleep_time)
175
+
176
+ templates_path = settings.BASE_DIR / "cbh" / "templates" / "emails"
177
+ env = Environment(
178
+ loader=FileSystemLoader(templates_path),
179
+ autoescape=select_autoescape(["html", "xml"]),
180
+ )
181
+ template = env.get_template("sessionReminderCoach.html")
182
+ template_content = template.render(
183
+ coach_name=call.coach.name,
184
+ user_name=call.customer.name,
185
+ start_date=call.event.startDate.strftime("%d %B %Y, %H:%M"),
186
+ join_link=f"{settings.Audience}/calls/{call.id}",
187
+ duration=(call.event.endDate - call.event.startDate).total_seconds() // 60,
188
+ )
189
+
190
+ await settings.EMAIL_CLIENT.send_email(
191
+ call.coach.email,
192
+ f"Your session with {call.customer.name} is starting in 1 hour.",
193
+ template_content,
194
+ )
cbh/api/calls/views.py CHANGED
@@ -31,7 +31,15 @@ from cbh.api.calls.services import (
31
  verify_discount_code,
32
  )
33
  from cbh.api.calls.services.daily import create_daily_token
34
- from cbh.api.calls.utils import can_edit_call
 
 
 
 
 
 
 
 
35
  from cbh.api.common.db_requests import get_obj_by_id
36
  from cbh.api.common.dto import Paging
37
  from cbh.api.common.schemas import AllObjectsResponse, FilterRequest
@@ -103,6 +111,8 @@ async def cancel_call(
103
  await refund_stripe_payment(call.paymentIntentId)
104
 
105
  call = await cancel_call_obj(call)
 
 
106
  return CbhResponseWrapper(data=call)
107
 
108
 
@@ -127,13 +137,17 @@ async def purchase_call(
127
 
128
 
129
  @calls_router.post("/stripe/callback")
130
- async def stripe_callback(request: Request) -> CbhResponseWrapper[None]:
131
  """
132
  Stripe callback.
133
  """
134
  payload = await request.body()
135
  event = verify_stripe_webhook(request, payload)
136
- await manage_stripe_event(event)
 
 
 
 
137
  return CbhResponseWrapper(data=None)
138
 
139
 
 
31
  verify_discount_code,
32
  )
33
  from cbh.api.calls.services.daily import create_daily_token
34
+ from cbh.api.calls.utils import (
35
+ can_edit_call,
36
+ send_coach_booking_email,
37
+ send_customer_booking_email,
38
+ send_cancel_customer_email,
39
+ send_cancel_coach_email,
40
+ send_session_reminder_email,
41
+ send_session_reminder_coach_email,
42
+ )
43
  from cbh.api.common.db_requests import get_obj_by_id
44
  from cbh.api.common.dto import Paging
45
  from cbh.api.common.schemas import AllObjectsResponse, FilterRequest
 
111
  await refund_stripe_payment(call.paymentIntentId)
112
 
113
  call = await cancel_call_obj(call)
114
+ # asyncio.create_task(send_cancel_customer_email(call))
115
+ # asyncio.create_task(send_cancel_coach_email(call))
116
  return CbhResponseWrapper(data=call)
117
 
118
 
 
137
 
138
 
139
  @calls_router.post("/stripe/callback")
140
+ async def stripe_callback(request: Request) -> CbhResponseWrapper:
141
  """
142
  Stripe callback.
143
  """
144
  payload = await request.body()
145
  event = verify_stripe_webhook(request, payload)
146
+ call = await manage_stripe_event(event)
147
+ # asyncio.create_task(send_customer_booking_email(call))
148
+ # asyncio.create_task(send_coach_booking_email(call))
149
+ # asyncio.create_task(send_session_reminder_email(call))
150
+ # asyncio.create_task(send_session_reminder_coach_email(call))
151
  return CbhResponseWrapper(data=None)
152
 
153
 
cbh/core/config.py CHANGED
@@ -10,6 +10,8 @@ from dotenv import load_dotenv
10
  from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
11
  from stripe import StripeClient
12
 
 
 
13
  load_dotenv()
14
 
15
 
@@ -31,6 +33,14 @@ class BaseConfig:
31
 
32
  DAILY_API_KEY = os.getenv("DAILY_API_KEY")
33
 
 
 
 
 
 
 
 
 
34
  @staticmethod
35
  def get_headers(api_key: str) -> dict:
36
  """
 
10
  from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
11
  from stripe import StripeClient
12
 
13
+ from cbh.core.email_client import EmailClient
14
+
15
  load_dotenv()
16
 
17
 
 
33
 
34
  DAILY_API_KEY = os.getenv("DAILY_API_KEY")
35
 
36
+ EMAIL_CLIENT = EmailClient(
37
+ smtp_server=os.getenv("SMTP_SERVER"),
38
+ port=int(os.getenv("PORT")),
39
+ sender_email=os.getenv("SENDER_EMAIL"),
40
+ password=os.getenv("PASSWORD"),
41
+ sender_name=os.getenv("SENDER_NAME"),
42
+ )
43
+
44
  @staticmethod
45
  def get_headers(api_key: str) -> dict:
46
  """
cbh/templates/emails/WeeklySummary.html DELETED
@@ -1,795 +0,0 @@
1
- {% extends "base.html" %}
2
-
3
- {% block title %}Weekly Report{% endblock %}
4
-
5
- {% block body_extra_style %}; background-color: #fafafa{% endblock %}
6
-
7
- {% block main %}
8
-
9
- <!-- Main Card -->
10
- <tr>
11
- <td style="padding: 0 20px 24px 20px">
12
- <table cellspacing="0" cellpadding="0" style="width: 100%">
13
- <tr>
14
- <td>
15
- <table cellspacing="0" cellpadding="0" style="background-color: #B8E5C5; border-radius: 12px; width: 100%">
16
- <tr>
17
- <td style="padding: 0 8px 8px 0">
18
- <table
19
- style="
20
- width: 100%;
21
- border: 1px solid #e4e4e7;
22
- border-radius: 12px;
23
- background-color: #ffffff;
24
- "
25
- cellspacing="0"
26
- cellpadding="0"
27
- >
28
- <tr>
29
- <td style="padding: 12px 24px; text-align: center">
30
- <h2
31
- style="
32
- font-size: 18px;
33
- font-weight: 600;
34
- color: #18181b;
35
- margin: 0 0 8px 0;
36
- "
37
- >
38
- Your weekly report
39
- </h2>
40
- <p
41
- style="
42
- font-size: 14px;
43
- color: #18181B;
44
- margin: 0 0 24px 0;
45
- "
46
- >
47
- Great work! Review your week's performance
48
- </p>
49
-
50
- <!-- See full report button -->
51
- <table
52
- cellspacing="0"
53
- cellpadding="0"
54
- style="margin: 0 auto 24px auto"
55
- >
56
- <tr>
57
- <td
58
- style="
59
- background-color: #31a152;
60
- border-radius: 8px;
61
- text-align: center;
62
- "
63
- >
64
- <a
65
- href="{{link}}"
66
- style="
67
- display: inline-block;
68
- padding: 8px 80px;
69
- color: #ffffff;
70
- text-decoration: none;
71
- font-size: 15px;
72
- font-weight: 500;
73
- "
74
- class="btn-mobile"
75
- >
76
- See full report
77
- </a>
78
- </td>
79
- </tr>
80
- </table>
81
- </td>
82
- </tr>
83
- </table>
84
- </td>
85
- </tr>
86
- </table>
87
- </td>
88
- </tr>
89
- </table>
90
- </td>
91
- </tr>
92
-
93
- <!-- Stats Section -->
94
- <tr>
95
- <td style="padding: 0 20px 16px 20px">
96
- <table
97
- style="
98
- width: 100%;
99
- border: 1px solid #E4E4E7;
100
- border-radius: 8px;
101
- "
102
- cellspacing="0"
103
- cellpadding="0"
104
- >
105
- <!-- Scenarios attempts -->
106
- <tr>
107
- <td
108
- style="
109
- padding: 12px 16px;
110
- border-bottom: 1px solid #E4E4E7;
111
- "
112
- >
113
- <table width="100%" cellspacing="0" cellpadding="0">
114
- <tr>
115
- <td style="vertical-align: middle">
116
- <span
117
- style="
118
- display: inline-block;
119
- vertical-align: middle;
120
- margin-right: 6px;
121
- "
122
- >
123
- <svg
124
- xmlns="http://www.w3.org/2000/svg"
125
- width="14"
126
- height="14"
127
- viewBox="0 0 24 24"
128
- fill="none"
129
- stroke="#e87b34"
130
- stroke-width="1.5"
131
- stroke-linecap="round"
132
- stroke-linejoin="round"
133
- class="lucide lucide-play-icon lucide-play"
134
- >
135
- <path
136
- d="M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z"
137
- />
138
- </svg>
139
- </span>
140
- <span style="
141
- display: inline-block;
142
- vertical-align: middle;
143
- font-size: 13px;
144
- color: #71717a;
145
- "
146
- >Scenarios attempts</span
147
- >
148
- </span>
149
- </td>
150
- <td
151
- style="
152
- text-align: right;
153
- vertical-align: middle;
154
- "
155
- >
156
- <span
157
- style="
158
- font-size: 18px;
159
- font-weight: 500;
160
- color: #18181b;
161
- "
162
- >{{attempts}}</span
163
- >
164
- </td>
165
- </tr>
166
- </table>
167
- </td>
168
- </tr>
169
-
170
- <!-- Avg score -->
171
- <tr>
172
- <td
173
- style="
174
- padding: 12px 16px;
175
- border-bottom: 1px solid #E4E4E7;
176
- "
177
- >
178
- <table width="100%" cellspacing="0" cellpadding="0">
179
- <tr>
180
- <td style="vertical-align: middle">
181
- <span
182
- style="
183
- display: inline-block;
184
- vertical-align: middle;
185
- margin-right: 6px;
186
- "
187
- >
188
- <svg
189
- xmlns="http://www.w3.org/2000/svg"
190
- width="14"
191
- height="14"
192
- viewBox="0 0 24 24"
193
- fill="none"
194
- stroke="#e2b53e"
195
- stroke-width="1.5"
196
- stroke-linecap="round"
197
- stroke-linejoin="round"
198
- class="lucide lucide-gem-icon lucide-gem"
199
- >
200
- <path d="M10.5 3 8 9l4 13 4-13-2.5-6" />
201
- <path
202
- d="M17 3a2 2 0 0 1 1.6.8l3 4a2 2 0 0 1 .013 2.382l-7.99 10.986a2 2 0 0 1-3.247 0l-7.99-10.986A2 2 0 0 1 2.4 7.8l2.998-3.997A2 2 0 0 1 7 3z"
203
- />
204
- <path d="M2 9h20" />
205
- </svg>
206
- </span>
207
- <span style="
208
- display: inline-block;
209
- vertical-align: middle;
210
- font-size: 13px;
211
- color: #71717a;
212
- "
213
- >Avg score</span
214
- >
215
- </td>
216
- <td
217
- style="
218
- text-align: right;
219
- vertical-align: middle;
220
- "
221
- >
222
- <span
223
- style="
224
- font-size: 18px;
225
- font-weight: 500;
226
- color: #18181b;
227
- "
228
- >{{avgScore}}%</span
229
- >
230
- </td>
231
- </tr>
232
- </table>
233
- </td>
234
- </tr>
235
-
236
- <!-- Avg time per session -->
237
- <tr>
238
- <td
239
- style="
240
- padding: 12px 16px;
241
- border-bottom: 1px solid #E4E4E7;
242
- "
243
- >
244
- <table width="100%" cellspacing="0" cellpadding="0">
245
- <tr>
246
- <td style="vertical-align: middle">
247
- <span
248
- style="
249
- display: inline-block;
250
- vertical-align: middle;
251
- margin-right: 6px;
252
- "
253
- >
254
- <svg
255
- xmlns="http://www.w3.org/2000/svg"
256
- width="14"
257
- height="14"
258
- viewBox="0 0 24 24"
259
- fill="none"
260
- stroke="currentColor"
261
- stroke-width="1.5"
262
- stroke-linecap="round"
263
- stroke-linejoin="round"
264
- class="lucide lucide-clock3-icon lucide-clock-3"
265
- >
266
- <path d="M12 6v6h4" />
267
- <circle cx="12" cy="12" r="10" />
268
- </svg>
269
- </span>
270
- <span
271
- style="
272
- display: inline-block;
273
- vertical-align: middle;
274
- font-size: 13px;
275
- color: #71717a;
276
- "
277
- >Avg time per session</span
278
- >
279
- </td>
280
- <td
281
- style="
282
- text-align: right;
283
- vertical-align: middle;
284
- "
285
- >
286
- <span
287
- style="
288
- font-size: 18px;
289
- font-weight: 500;
290
- color: #18181b;
291
- "
292
- >{{avgTimePerSession}}</span
293
- >
294
- </td>
295
- </tr>
296
- </table>
297
- </td>
298
- </tr>
299
-
300
- <!-- Top skill -->
301
- <tr>
302
- <td
303
- style="
304
- padding: 12px 16px;
305
- border-bottom: 1px solid #E4E4E7;
306
- "
307
- >
308
- <table width="100%" cellspacing="0" cellpadding="0">
309
- <tr>
310
- <td style="vertical-align: middle">
311
- <span
312
- style="
313
- display: inline-block;
314
- vertical-align: middle;
315
- margin-right: 6px;
316
- "
317
- >
318
- <svg
319
- xmlns="http://www.w3.org/2000/svg"
320
- width="14"
321
- height="14"
322
- viewBox="0 0 24 24"
323
- fill="none"
324
- stroke="#e87b34"
325
- stroke-width="1.5"
326
- stroke-linecap="round"
327
- stroke-linejoin="round"
328
- class="lucide lucide-award-icon lucide-award"
329
- >
330
- <path
331
- d="m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526"
332
- />
333
- <circle cx="12" cy="8" r="6" />
334
- </svg>
335
- </span>
336
- <span
337
- style="
338
- display: inline-block;
339
- vertical-align: middle;
340
- font-size: 13px;
341
- color: #71717a;
342
- "
343
- >Top skill</span
344
- >
345
- </td>
346
- <td
347
- style="
348
- text-align: right;
349
- vertical-align: middle;
350
- "
351
- >
352
- <div
353
- style="
354
- font-size: 18px;
355
- font-weight: 500;
356
- color: #18181b;
357
- "
358
- >
359
- {{topSkill}}
360
- </div>
361
- <div
362
- style="
363
- font-size: 12px;
364
- color: #71717a;
365
- "
366
- >
367
- {{topSkillScore}}% Score
368
- </div>
369
- </td>
370
- </tr>
371
- </table>
372
- </td>
373
- </tr>
374
-
375
- <!-- Bottom skill -->
376
- <tr>
377
- <td
378
- style="
379
- padding: 12px 16px;
380
- border-bottom: 1px solid #E4E4E7;
381
- "
382
- >
383
- <table width="100%" cellspacing="0" cellpadding="0">
384
- <tr>
385
- <td style="vertical-align: middle">
386
- <span
387
- style="
388
- display: inline-block;
389
- vertical-align: middle;
390
- margin-right: 6px;
391
- "
392
- >
393
- <svg
394
- xmlns="http://www.w3.org/2000/svg"
395
- width="14"
396
- height="14"
397
- viewBox="0 0 24 24"
398
- fill="none"
399
- stroke="#e87b34"
400
- stroke-width="1.5"
401
- stroke-linecap="round"
402
- stroke-linejoin="round"
403
- class="lucide lucide-award-icon lucide-award"
404
- >
405
- <path
406
- d="m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526"
407
- />
408
- <circle cx="12" cy="8" r="6" />
409
- </svg>
410
- </span>
411
- <span
412
- style="
413
- display: inline-block;
414
- vertical-align: middle;
415
- font-size: 13px;
416
- color: #71717a;
417
- "
418
- >Bottom skill</span
419
- >
420
- </td>
421
- <td
422
- style="
423
- text-align: right;
424
- vertical-align: middle;
425
- "
426
- >
427
- <div
428
- style="
429
- font-size: 18px;
430
- font-weight: 500;
431
- color: #18181b;
432
- "
433
- >
434
- {{bottomSkill}}
435
- </div>
436
- <div
437
- style="
438
- font-size: 12px;
439
- color: #71717a;
440
- "
441
- >
442
- {{bottomSkillScore}}% Score
443
- </div>
444
- </td>
445
- </tr>
446
- </table>
447
- </td>
448
- </tr>
449
-
450
- <!-- Leaderboard position -->
451
- <tr>
452
- <td style="padding: 12px 16px">
453
- <table width="100%" cellspacing="0" cellpadding="0">
454
- <tr>
455
- <td style="vertical-align: middle">
456
- <span
457
- style="
458
- display: inline-block;
459
- vertical-align: middle;
460
- margin-right: 6px;
461
- "
462
- >
463
- <svg
464
- xmlns="http://www.w3.org/2000/svg"
465
- width="14"
466
- height="14"
467
- viewBox="0 0 24 24"
468
- fill="none"
469
- stroke="#4e80ee"
470
- stroke-width="1.5"
471
- stroke-linecap="round"
472
- stroke-linejoin="round"
473
- class="lucide lucide-user"
474
- >
475
- <path
476
- d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"
477
- />
478
- <circle cx="12" cy="7" r="4" />
479
- </svg>
480
- </span>
481
- <span
482
- style="
483
- display: inline-block;
484
- vertical-align: middle;
485
- font-size: 13px;
486
- color: #71717a;
487
- "
488
- >
489
- Leaderboard
490
- </span>
491
- </td>
492
- <td
493
- style="
494
- text-align: right;
495
- vertical-align: middle;
496
- "
497
- >
498
- <div
499
- style="
500
- font-size: 18px;
501
- font-weight: 500;
502
- color: #18181b;
503
- "
504
- >
505
- {{leaderboardPosition}} position
506
- </div>
507
- {% if lastLeaderboardPosition %}
508
- <div
509
- style="
510
- font-size: 12px;
511
- color: #71717a;
512
- "
513
- >
514
- Last week: {{lastLeaderboardPosition}} position
515
- </div>
516
- {% endif %}
517
- </td>
518
- </tr>
519
- </table>
520
- </td>
521
- </tr>
522
- </table>
523
- </td>
524
- </tr>
525
-
526
- <!-- Top achievements -->
527
- <tr>
528
- <td style="padding: 0 20px 16px 20px">
529
- <table
530
- style="
531
- width: 100%;
532
- border: 1px solid #E4E4E7;
533
- border-radius: 8px;
534
- "
535
- cellspacing="0"
536
- cellpadding="0"
537
- >
538
- <tr>
539
- <td style="padding: 16px 20px">
540
- <div
541
- style="
542
- display: inline-flex;
543
- align-items: center;
544
- gap: 6px;
545
- margin-bottom: 8px;
546
- "
547
- >
548
- <svg
549
- xmlns="http://www.w3.org/2000/svg"
550
- width="16"
551
- height="16"
552
- viewBox="0 0 24 24"
553
- fill="none"
554
- stroke="#5ec269"
555
- stroke-width="1.5"
556
- stroke-linecap="round"
557
- stroke-linejoin="round"
558
- class="lucide lucide-biceps-flexed-icon lucide-biceps-flexed"
559
- >
560
- <path
561
- d="M12.409 13.017A5 5 0 0 1 22 15c0 3.866-4 7-9 7-4.077 0-8.153-.82-10.371-2.462-.426-.316-.631-.832-.62-1.362C2.118 12.723 2.627 2 10 2a3 3 0 0 1 3 3 2 2 0 0 1-2 2c-1.105 0-1.64-.444-2-1"
562
- />
563
- <path d="M15 14a5 5 0 0 0-7.584 2" />
564
- <path d="M9.964 6.825C8.019 7.977 9.5 13 8 15" />
565
- </svg>
566
- <span
567
- style="
568
- font-size: 14px;
569
- color: #18181b;
570
- "
571
- >Top achievements</span
572
- >
573
- </div>
574
-
575
- <!-- Achievement items -->
576
- {% for achievement in topAchievements %}
577
- <div
578
- style="
579
- background-color: #f0fdf4;
580
- border-radius: 6px;
581
- padding: 12px;
582
- margin-bottom: 8px;
583
- "
584
- >
585
- <div
586
- style="
587
- font-size: 13px;
588
- font-weight: 600;
589
- color: #18181b;
590
- margin-bottom: 4px;
591
- "
592
- >
593
- {{achievement.name}}
594
- </div>
595
- <div style="font-size: 12px; color: #71717a">
596
- {{achievement.description}}
597
- </div>
598
- </div>
599
- {% endfor %}
600
- </td>
601
- </tr>
602
- </table>
603
- </td>
604
- </tr>
605
-
606
- <!-- Needs work -->
607
- <tr>
608
- <td style="padding: 0 20px 16px 20px">
609
- <table
610
- style="
611
- width: 100%;
612
- border: 1px solid #e4e4e7;
613
- border-radius: 8px;
614
- "
615
- cellspacing="0"
616
- cellpadding="0"
617
- >
618
- <tr>
619
- <td style="padding: 16px 20px">
620
- <div
621
- style="
622
- display: inline-flex;
623
- align-items: center;
624
- gap: 6px;
625
- margin-bottom: 8px;
626
- "
627
- >
628
- <svg
629
- xmlns="http://www.w3.org/2000/svg"
630
- width="16"
631
- height="16"
632
- viewBox="0 0 24 24"
633
- fill="none"
634
- stroke="#e87b34"
635
- stroke-width="1.5"
636
- stroke-linecap="round"
637
- stroke-linejoin="round"
638
- class="lucide lucide-wrench-icon lucide-wrench"
639
- >
640
- <path
641
- d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"
642
- />
643
- </svg>
644
- <span
645
- style="
646
- font-size: 14px;
647
- color: #18181b;
648
- "
649
- >Needs work</span
650
- >
651
- </div>
652
-
653
- <!-- Improvement items -->
654
- {% for mistake in topMistakes %}
655
- <div
656
- style="
657
- background-color: #fff7ed;
658
- border-radius: 6px;
659
- padding: 12px;
660
- margin-bottom: 8px;
661
- "
662
- >
663
- <div
664
- style="
665
- font-size: 13px;
666
- font-weight: 600;
667
- color: #18181b;
668
- margin-bottom: 4px;
669
- "
670
- >
671
- {{mistake.name}}
672
- </div>
673
- <div style="font-size: 12px; color: #71717a">
674
- {{mistake.description}}
675
- </div>
676
- </div>
677
- {% endfor %}
678
- </td>
679
- </tr>
680
- </table>
681
- </td>
682
- </tr>
683
-
684
- <!-- AI Insights -->
685
- <tr>
686
- <td style="padding: 0 20px 24px 20px">
687
- <table
688
- style="
689
- width: 100%;
690
- border: 1px solid #e4e4e7;
691
- border-radius: 8px;
692
- background: linear-gradient(135deg, #fffbe6 0%, #ffeaf3 50%, #f0f0ff 100%);
693
- "
694
- cellspacing="0"
695
- cellpadding="0"
696
- >
697
- <tr>
698
- <td style="padding: 16px 20px">
699
- <div
700
- style="
701
- display: inline-flex;
702
- align-items: center;
703
- gap: 6px;
704
- margin-bottom: 8px;
705
- "
706
- >
707
- <svg
708
- xmlns="http://www.w3.org/2000/svg"
709
- width="16"
710
- height="16"
711
- viewBox="0 0 24 24"
712
- fill="none"
713
- stroke="#845eee"
714
- stroke-width="1.5"
715
- stroke-linecap="round"
716
- stroke-linejoin="round"
717
- class="lucide lucide-wand-sparkles-icon lucide-wand-sparkles"
718
- >
719
- <path
720
- d="m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72"
721
- />
722
- <path d="m14 7 3 3" />
723
- <path d="M5 6v4" />
724
- <path d="M19 14v4" />
725
- <path d="M10 2v2" />
726
- <path d="M7 8H3" />
727
- <path d="M21 16h-4" />
728
- <path d="M11 3H9" />
729
- </svg>
730
- <span
731
- style="
732
- font-size: 14px;
733
- font-weight: 500;
734
- color: #18181b;
735
- "
736
- >AI Insights</span
737
- >
738
- </div>
739
- <ul
740
- style="
741
- font-size: 13px;
742
- font-weight: 500;
743
- color: #18181b;
744
- margin: 0;
745
- padding-left: 20px;
746
- "
747
- >
748
- {% for insight in aiInsights %}
749
- <li style="margin-bottom: 4px;">{{insight}}</li>
750
- {% endfor %}
751
- </ul>
752
- </td>
753
- </tr>
754
- </table>
755
- </td>
756
- </tr>
757
-
758
- <!-- Bottom Button -->
759
- <tr>
760
- <td style="padding: 0 20px 24px 20px">
761
- <table
762
- cellspacing="0"
763
- cellpadding="0"
764
- style="margin: 0 auto; width: 100%"
765
- >
766
- <tr>
767
- <td
768
- style="
769
- background-color: #31a152;
770
- border-radius: 8px;
771
- text-align: center;
772
- "
773
- >
774
- <a
775
- href="{{link}}"
776
- style="
777
- display: inline-block;
778
- padding: 8px 80px;
779
- color: #ffffff;
780
- text-decoration: none;
781
- font-size: 15px;
782
- font-weight: 500;
783
- width: 100%;
784
- box-sizing: border-box;
785
- "
786
- class="btn-mobile"
787
- >
788
- See full report
789
- </a>
790
- </td>
791
- </tr>
792
- </table>
793
- </td>
794
- </tr>
795
- {% endblock %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cbh/templates/emails/WeeklySummaryAdmin.html DELETED
@@ -1,620 +0,0 @@
1
- {% extends "base.html" %}
2
-
3
- {% block title %}Weekly Report{% endblock %}
4
-
5
- {% block body_extra_style %}; background-color: #fafafa{% endblock %}
6
-
7
- {% block main %}
8
-
9
- <!-- Main Card -->
10
- <tr>
11
- <td style="padding: 0 20px 24px 20px">
12
- <table
13
- style="
14
- width: 100%;
15
- border: 1px solid #e4e4e7;
16
- border-radius: 12px;
17
- box-shadow: 8px 8px 0px 0px #b8e5c5;
18
- "
19
- cellspacing="0"
20
- cellpadding="0"
21
- >
22
- <tr>
23
- <td style="padding: 12px 24px; text-align: center">
24
- <h2
25
- style="
26
- font-size: 18px;
27
- font-weight: 600;
28
- color: #18181b;
29
- margin: 0 0 8px 0;
30
- "
31
- >
32
- Your weekly report
33
- </h2>
34
- <p
35
- style="
36
- font-size: 14px;
37
- color: #18181B;
38
- margin: 0 0 24px 0;
39
- "
40
- >
41
- Your team is killing it! Review this week’s performance
42
- </p>
43
-
44
- <!-- See full report button -->
45
- <table
46
- cellspacing="0"
47
- cellpadding="0"
48
- style="margin: 0 auto 24px auto"
49
- >
50
- <tr>
51
- <td
52
- style="
53
- background-color: #31a152;
54
- border-radius: 8px;
55
- text-align: center;
56
- "
57
- >
58
- <a
59
- href="{{link}}"
60
- style="
61
- display: inline-block;
62
- padding: 8px 80px;
63
- color: #ffffff;
64
- text-decoration: none;
65
- font-size: 15px;
66
- font-weight: 500;
67
- "
68
- class="btn-mobile"
69
- >
70
- See full report
71
- </a>
72
- </td>
73
- </tr>
74
- </table>
75
- </td>
76
- </tr>
77
- </table>
78
- </td>
79
- </tr>
80
-
81
- <!-- Stats Section -->
82
- <tr>
83
- <td style="padding: 0 20px 16px 20px">
84
- <table
85
- style="
86
- width: 100%;
87
- border: 1px solid #E4E4E7;
88
- border-radius: 8px;
89
- "
90
- cellspacing="0"
91
- cellpadding="0"
92
- >
93
- <!-- Scenarios attempts -->
94
- <tr>
95
- <td
96
- style="
97
- padding: 16px 20px;
98
- border-bottom: 1px solid #E4E4E7;
99
- "
100
- >
101
- <table width="100%" cellspacing="0" cellpadding="0">
102
- <tr>
103
- <td style="vertical-align: middle">
104
- <span
105
- style="
106
- display: inline-block;
107
- vertical-align: middle;
108
- margin-right: 6px;
109
- "
110
- >
111
- <svg
112
- xmlns="http://www.w3.org/2000/svg"
113
- width="16"
114
- height="16"
115
- viewBox="0 0 24 24"
116
- fill="none"
117
- stroke="#e87b34"
118
- stroke-width="1.5"
119
- stroke-linecap="round"
120
- stroke-linejoin="round"
121
- class="lucide lucide-play-icon lucide-play"
122
- >
123
- <path
124
- d="M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z"
125
- />
126
- </svg>
127
- </span>
128
- <span style="
129
- display: inline-block;
130
- vertical-align: middle;
131
- font-size: 14px;
132
- color: #71717a;
133
- "
134
- >Scenarios attempts</span
135
- >
136
- </span>
137
- </td>
138
- <td
139
- style="
140
- text-align: right;
141
- vertical-align: middle;
142
- "
143
- >
144
- <span
145
- style="
146
- font-size: 20px;
147
- font-weight: 500;
148
- color: #18181b;
149
- "
150
- >{{attempts}}</span
151
- >
152
- </td>
153
- </tr>
154
- </table>
155
- </td>
156
- </tr>
157
-
158
- <!-- Avg score -->
159
- <tr>
160
- <td
161
- style="
162
- padding: 16px 20px;
163
- border-bottom: 1px solid #E4E4E7;
164
- "
165
- >
166
- <table width="100%" cellspacing="0" cellpadding="0">
167
- <tr>
168
- <td style="vertical-align: middle">
169
- <span
170
- style="
171
- display: inline-block;
172
- vertical-align: middle;
173
- margin-right: 6px;
174
- "
175
- >
176
- <svg
177
- xmlns="http://www.w3.org/2000/svg"
178
- width="16"
179
- height="16"
180
- viewBox="0 0 24 24"
181
- fill="none"
182
- stroke="#e2b53e"
183
- stroke-width="1.5"
184
- stroke-linecap="round"
185
- stroke-linejoin="round"
186
- class="lucide lucide-gem-icon lucide-gem"
187
- >
188
- <path d="M10.5 3 8 9l4 13 4-13-2.5-6" />
189
- <path
190
- d="M17 3a2 2 0 0 1 1.6.8l3 4a2 2 0 0 1 .013 2.382l-7.99 10.986a2 2 0 0 1-3.247 0l-7.99-10.986A2 2 0 0 1 2.4 7.8l2.998-3.997A2 2 0 0 1 7 3z"
191
- />
192
- <path d="M2 9h20" />
193
- </svg>
194
- </span>
195
- <span style="
196
- display: inline-block;
197
- vertical-align: middle;
198
- font-size: 14px;
199
- color: #71717a;
200
- "
201
- >Avg score</span
202
- >
203
- </td>
204
- <td
205
- style="
206
- text-align: right;
207
- vertical-align: middle;
208
- "
209
- >
210
- <span
211
- style="
212
- font-size: 20px;
213
- font-weight: 500;
214
- color: #18181b;
215
- "
216
- >{{avgScore}}%</span
217
- >
218
- </td>
219
- </tr>
220
- </table>
221
- </td>
222
- </tr>
223
-
224
- <!-- Avg time per session -->
225
- <tr>
226
- <td
227
- style="
228
- padding: 16px 20px;
229
- border-bottom: 1px solid #E4E4E7;
230
- "
231
- >
232
- <table width="100%" cellspacing="0" cellpadding="0">
233
- <tr>
234
- <td style="vertical-align: middle">
235
- <span
236
- style="
237
- display: inline-block;
238
- vertical-align: middle;
239
- margin-right: 6px;
240
- "
241
- >
242
- <svg
243
- xmlns="http://www.w3.org/2000/svg"
244
- width="16"
245
- height="16"
246
- viewBox="0 0 24 24"
247
- fill="none"
248
- stroke="currentColor"
249
- stroke-width="1.5"
250
- stroke-linecap="round"
251
- stroke-linejoin="round"
252
- class="lucide lucide-clock3-icon lucide-clock-3"
253
- >
254
- <path d="M12 6v6h4" />
255
- <circle cx="12" cy="12" r="10" />
256
- </svg>
257
- </span>
258
- <span
259
- style="
260
- display: inline-block;
261
- vertical-align: middle;
262
- font-size: 14px;
263
- color: #71717a;
264
- "
265
- >Avg time per session</span
266
- >
267
- </td>
268
- <td
269
- style="
270
- text-align: right;
271
- vertical-align: middle;
272
- "
273
- >
274
- <span
275
- style="
276
- font-size: 20px;
277
- font-weight: 500;
278
- color: #18181b;
279
- "
280
- >{{avgTimePerSession}}</span
281
- >
282
- </td>
283
- </tr>
284
- </table>
285
- </td>
286
- </tr>
287
- <!-- Top representative -->
288
- <tr>
289
- <td
290
- style="
291
- padding: 16px 20px;
292
- border-bottom: 1px solid #E4E4E7;
293
- "
294
- >
295
- <table width="100%" cellspacing="0" cellpadding="0">
296
- <tr>
297
- <td style="vertical-align: middle">
298
- <span
299
- style="
300
- display: inline-block;
301
- vertical-align: middle;
302
- margin-right: 6px;
303
- "
304
- >
305
- <svg
306
- xmlns="http://www.w3.org/2000/svg"
307
- width="16"
308
- height="16"
309
- viewBox="0 0 24 24"
310
- fill="none"
311
- stroke="#4e80ee"
312
- stroke-width="1.5"
313
- stroke-linecap="round"
314
- stroke-linejoin="round"
315
- class="lucide lucide-user"
316
- >
317
- <path
318
- d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"
319
- />
320
- <circle cx="12" cy="7" r="4" />
321
- </svg>
322
- </span>
323
- <span
324
- style="
325
- display: inline-block;
326
- vertical-align: middle;
327
- font-size: 14px;
328
- color: #71717a;
329
- "
330
- >
331
- Top sales rep
332
- </span>
333
- </td>
334
- <td
335
- style="
336
- text-align: right;
337
- vertical-align: middle;
338
- "
339
- >
340
- <div
341
- style="
342
- font-size: 18px;
343
- font-weight: 600;
344
- color: #18181b;
345
- "
346
- >
347
- {{bestAccount}}
348
- </div>
349
- <div
350
- style="
351
- font-size: 12px;
352
- color: #71717a;
353
- font-weight: 500;
354
- "
355
- >
356
- {{bestAccountScore}}% avg score
357
- </div>
358
- </td>
359
- </tr>
360
- </table>
361
- </td>
362
- </tr>
363
-
364
- <!-- Bottom representative -->
365
- <tr>
366
- <td style="padding: 16px 20px">
367
- <table width="100%" cellspacing="0" cellpadding="0">
368
- <tr>
369
- <td style="vertical-align: middle">
370
- <span
371
- style="
372
- display: inline-block;
373
- vertical-align: middle;
374
- margin-right: 6px;
375
- "
376
- >
377
- <svg
378
- xmlns="http://www.w3.org/2000/svg"
379
- width="16"
380
- height="16"
381
- viewBox="0 0 24 24"
382
- fill="none"
383
- stroke="#4e80ee"
384
- stroke-width="1.5"
385
- stroke-linecap="round"
386
- stroke-linejoin="round"
387
- class="lucide lucide-user"
388
- >
389
- <path
390
- d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"
391
- />
392
- <circle cx="12" cy="7" r="4" />
393
- </svg>
394
- </span>
395
- <span
396
- style="
397
- display: inline-block;
398
- vertical-align: middle;
399
- font-size: 14px;
400
- color: #71717a;
401
- "
402
- >
403
- Bottom sales rep
404
- </span>
405
- </td>
406
- <td
407
- style="
408
- text-align: right;
409
- vertical-align: middle;
410
- "
411
- >
412
- <div
413
- style="
414
- font-size: 18px;
415
- font-weight: 600;
416
- color: #18181b;
417
- "
418
- >
419
- {{bottomAccount}}
420
- </div>
421
- <div
422
- style="
423
- font-size: 12px;
424
- color: #71717a;
425
- font-weight: 500;
426
- "
427
- >
428
- {{bottomAccountScore}}% avg score
429
- </div>
430
- </td>
431
- </tr>
432
- </table>
433
- </td>
434
- </tr>
435
- </table>
436
- </td>
437
- </tr>
438
-
439
- <!-- Most common mistakes -->
440
- <tr>
441
- <td style="padding: 0 20px 16px 20px">
442
- <table
443
- style="
444
- width: 100%;
445
- border: 1px solid #E4E4E7;
446
- border-radius: 8px;
447
- "
448
- cellspacing="0"
449
- cellpadding="0"
450
- >
451
- <tr>
452
- <td style="padding: 16px 20px">
453
- <div
454
- style="
455
- display: inline-flex;
456
- align-items: center;
457
- gap: 6px;
458
- margin-bottom: 8px;
459
- "
460
- >
461
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#dd524b" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw-icon lucide-rotate-cw"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/></svg>
462
- <span
463
- style="
464
- font-size: 14px;
465
- color: #18181b;
466
- "
467
- >Most common mistakes across attempts</span
468
- >
469
- </div>
470
-
471
- <!-- Mistake items -->
472
- {% for insight in topMistakes %}
473
- <div
474
- style="
475
- margin-bottom: 8px;
476
- padding: 12px;
477
- background-color: #fffbeb;
478
- border-radius: 8px;
479
- "
480
- >
481
- <div
482
- style="
483
- font-size: 14px;
484
- font-weight: 600;
485
- color: #18181b;
486
- margin-bottom: 4px;
487
- "
488
- >
489
- {{insight.name}}
490
- </div>
491
- <div
492
- style="
493
- font-size: 12px;
494
- color: #18181b;
495
- line-height: 1.4;
496
- "
497
- >
498
- {{insight.description}}
499
- </div>
500
- </div>
501
- {% endfor %}
502
- </td>
503
- </tr>
504
- </table>
505
- </td>
506
- </tr>
507
-
508
- <!-- AI Insights -->
509
- <tr>
510
- <td style="padding: 0 20px 24px 20px">
511
- <table
512
- style="
513
- width: 100%;
514
- border: 1px solid #e4e4e7;
515
- border-radius: 8px;
516
- background: linear-gradient(135deg, #fffbe6 0%, #ffeaf3 50%, #f0f0ff 100%);
517
- "
518
- cellspacing="0"
519
- cellpadding="0"
520
- >
521
- <tr>
522
- <td style="padding: 16px 20px">
523
- <div
524
- style="
525
- display: inline-flex;
526
- align-items: center;
527
- gap: 6px;
528
- margin-bottom: 8px;
529
- "
530
- >
531
- <svg
532
- xmlns="http://www.w3.org/2000/svg"
533
- width="16"
534
- height="16"
535
- viewBox="0 0 24 24"
536
- fill="none"
537
- stroke="#845eee"
538
- stroke-width="1.5"
539
- stroke-linecap="round"
540
- stroke-linejoin="round"
541
- class="lucide lucide-wand-sparkles-icon lucide-wand-sparkles"
542
- >
543
- <path
544
- d="m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72"
545
- />
546
- <path d="m14 7 3 3" />
547
- <path d="M5 6v4" />
548
- <path d="M19 14v4" />
549
- <path d="M10 2v2" />
550
- <path d="M7 8H3" />
551
- <path d="M21 16h-4" />
552
- <path d="M11 3H9" />
553
- </svg>
554
- <span
555
- style="
556
- font-size: 14px;
557
- font-weight: 500;
558
- color: #18181b;
559
- "
560
- >AI Insights</span
561
- >
562
- </div>
563
- <ul
564
- style="
565
- font-size: 13px;
566
- font-weight: 500;
567
- color: #18181b;
568
- margin: 0;
569
- padding-left: 20px;
570
- "
571
- >
572
- {% for insight in aiInsights %}
573
- <li style="margin-bottom: 4px;">{{insight}}</li>
574
- {% endfor %}
575
- </ul>
576
- </td>
577
- </tr>
578
- </table>
579
- </td>
580
- </tr>
581
-
582
-
583
- <!-- Bottom Button -->
584
- <tr>
585
- <td style="padding: 0 20px 24px 20px">
586
- <table
587
- cellspacing="0"
588
- cellpadding="0"
589
- style="margin: 0 auto; width: 100%"
590
- >
591
- <tr>
592
- <td
593
- style="
594
- background-color: #31a152;
595
- border-radius: 8px;
596
- text-align: center;
597
- "
598
- >
599
- <a
600
- href="{{link}}"
601
- style="
602
- display: inline-block;
603
- padding: 8px 80px;
604
- color: #ffffff;
605
- text-decoration: none;
606
- font-size: 15px;
607
- font-weight: 500;
608
- width: 100%;
609
- box-sizing: border-box;
610
- "
611
- class="btn-mobile"
612
- >
613
- See full report
614
- </a>
615
- </td>
616
- </tr>
617
- </table>
618
- </td>
619
- </tr>
620
- {% endblock %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cbh/templates/emails/base.html CHANGED
@@ -6,7 +6,7 @@
6
  <meta name="x-apple-disable-message-reformatting" />
7
  <link rel="preconnect" href="https://fonts.googleapis.com" />
8
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
- <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@100;400;500;600;700&display=swap" rel="stylesheet" />
10
  <style>
11
  @media only screen and (max-width: 480px) {
12
  a.btn-mobile {
@@ -20,15 +20,15 @@
20
  {% block head %}{% endblock %}
21
  </head>
22
  <body>
23
- <div style="font-family: Poppins, sans-serif; margin: 0; padding: 20px{% block body_extra_style %}{% endblock %}">
24
- <table style="max-width: 500px; margin: 0 auto; background-color: #ffffff" cellspacing="0" cellpadding="0">
25
  {% block header %}
26
  <tr>
27
- <td style="padding: 10px; text-align: center">
28
  <table cellpadding="0" cellspacing="0" style="margin: 0 auto">
29
  <tr>
30
  <td style="vertical-align: middle">
31
- <img src="https://trainwitharena.com/logo-email.png" alt="Arena Logo" style="height: 20px; vertical-align: middle" />
32
  </td>
33
  </tr>
34
  </table>
@@ -42,22 +42,15 @@
42
 
43
  {% block footer %}
44
  <tr>
45
- <td style="padding: 30px 40px">
46
  <table width="100%" cellpadding="0" cellspacing="0">
47
  <tr>
48
- <td style="vertical-align: top">
49
- <table cellpadding="0" cellspacing="0" style="margin-bottom: 12px">
50
- <tr>
51
- <td style="vertical-align: middle">
52
- <img src="https://trainwitharena.com/logo-email.png" alt="Arena Logo" style="height: 20px; vertical-align: middle" />
53
- </td>
54
- </tr>
55
- </table>
56
- <p style="font-size: 12px; font-weight: 400; color: #6b6e76; line-height: 1.6; margin: 0;">
57
- Arena is a service of Clipboard Health LLC., a licensed provider of health organization services.
58
- All money transmission is provided by Clipboard Health LLC, pursuant to Clipboard Health LLC's licenses.
59
- <br /><br />
60
- Clipboard Health is located at 2211 North First Street, San Jose, CA 95131
61
  </p>
62
  </td>
63
  </tr>
 
6
  <meta name="x-apple-disable-message-reformatting" />
7
  <link rel="preconnect" href="https://fonts.googleapis.com" />
8
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
10
  <style>
11
  @media only screen and (max-width: 480px) {
12
  a.btn-mobile {
 
20
  {% block head %}{% endblock %}
21
  </head>
22
  <body>
23
+ <div style="font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; margin: 0; padding: 20px; background-color: #f8f9fa{% block body_extra_style %}{% endblock %}">
24
+ <table style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 16px; overflow: hidden" cellspacing="0" cellpadding="0">
25
  {% block header %}
26
  <tr>
27
+ <td style="padding: 32px 40px 24px 40px; text-align: center; background: linear-gradient(135deg, #54949D 0%, #54949D 100%)">
28
  <table cellpadding="0" cellspacing="0" style="margin: 0 auto">
29
  <tr>
30
  <td style="vertical-align: middle">
31
+ <img src="https://spark-alpha-eight.vercel.app/logo.svg" alt="Spark Logo" style="height: 40px; vertical-align: middle" />
32
  </td>
33
  </tr>
34
  </table>
 
42
 
43
  {% block footer %}
44
  <tr>
45
+ <td style="padding: 32px 40px; background-color: #f8f9fa; border-top: 1px solid #e9ecef">
46
  <table width="100%" cellpadding="0" cellspacing="0">
47
  <tr>
48
+ <td style="text-align: center">
49
+ <p style="font-size: 13px; font-weight: 400; color: #6c757d; line-height: 1.6; margin: 0 0 12px 0;">
50
+ Need help? Contact us at <a href="mailto:support@spark.com" style="color: #54949D; text-decoration: none;">support@spark.com</a>
51
+ </p>
52
+ <p style="font-size: 12px; font-weight: 400; color: #adb5bd; line-height: 1.6; margin: 0;">
53
+ © 2026 Spark. All rights reserved.
 
 
 
 
 
 
 
54
  </p>
55
  </td>
56
  </tr>
cbh/templates/emails/bookingConfirmation.html ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}Booking Confirmed - Your Session with {{coach_name}}{% endblock %}
4
+
5
+ {% block main %}
6
+ <tr>
7
+ <td style="padding: 40px 40px 32px 40px">
8
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
9
+ <tr>
10
+ <td style="text-align: center">
11
+ <div style="
12
+ display: inline-block;
13
+ background-color: #d4edda;
14
+ border-radius: 50%;
15
+ padding: 16px;
16
+ margin: 0 0 24px 0;
17
+ ">
18
+ <div style="
19
+ width: 48px;
20
+ height: 48px;
21
+ background-color: #28a745;
22
+ border-radius: 50%;
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ ">
27
+ <span style="color: #ffffff; font-size: 32px; line-height: 1;">✓</span>
28
+ </div>
29
+ </div>
30
+
31
+ <h1 style="
32
+ font-size: 28px;
33
+ font-weight: 600;
34
+ color: #212529;
35
+ margin: 0 0 12px 0;
36
+ line-height: 1.3;
37
+ ">
38
+ Booking Confirmed!
39
+ </h1>
40
+
41
+ <p style="
42
+ font-size: 16px;
43
+ color: #6c757d;
44
+ margin: 0 0 32px 0;
45
+ line-height: 1.6;
46
+ ">
47
+ Hi {{user_name}}, your coaching session has been successfully booked.<br/>
48
+ We're excited to help you on your journey!
49
+ </p>
50
+ </td>
51
+ </tr>
52
+ </table>
53
+
54
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 32px">
55
+ <tr>
56
+ <td>
57
+ <div style="
58
+ background: linear-gradient(135deg, #54949D 0%, #4a8289 100%);
59
+ border-radius: 12px;
60
+ padding: 24px;
61
+ color: #ffffff;
62
+ ">
63
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
64
+ <tr>
65
+ <td style="padding-bottom: 20px; border-bottom: 1px solid rgba(255, 255, 255, 0.2)">
66
+ <p style="
67
+ font-size: 13px;
68
+ font-weight: 500;
69
+ color: rgba(255, 255, 255, 0.8);
70
+ margin: 0 0 8px 0;
71
+ text-transform: uppercase;
72
+ letter-spacing: 0.5px;
73
+ ">
74
+ Your Coach
75
+ </p>
76
+ <p style="
77
+ font-size: 20px;
78
+ font-weight: 600;
79
+ color: #ffffff;
80
+ margin: 0;
81
+ ">
82
+ {{coach_name}}
83
+ </p>
84
+ </td>
85
+ </tr>
86
+ <tr>
87
+ <td style="padding-top: 20px">
88
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
89
+ <tr>
90
+ <td style="width: 50%; vertical-align: top; padding-right: 12px">
91
+ <p style="
92
+ font-size: 13px;
93
+ font-weight: 500;
94
+ color: rgba(255, 255, 255, 0.8);
95
+ margin: 0 0 8px 0;
96
+ text-transform: uppercase;
97
+ letter-spacing: 0.5px;
98
+ ">
99
+ Date & Time
100
+ </p>
101
+ <p style="
102
+ font-size: 16px;
103
+ font-weight: 600;
104
+ color: #ffffff;
105
+ margin: 0;
106
+ ">
107
+ {{start_date}}
108
+ </p>
109
+ </td>
110
+ <td style="width: 50%; vertical-align: top; padding-left: 12px">
111
+ <p style="
112
+ font-size: 13px;
113
+ font-weight: 500;
114
+ color: rgba(255, 255, 255, 0.8);
115
+ margin: 0 0 8px 0;
116
+ text-transform: uppercase;
117
+ letter-spacing: 0.5px;
118
+ ">
119
+ Duration
120
+ </p>
121
+ <p style="
122
+ font-size: 16px;
123
+ font-weight: 600;
124
+ color: #ffffff;
125
+ margin: 0;
126
+ ">
127
+ {{duration}} minutes
128
+ </p>
129
+ </td>
130
+ </tr>
131
+ </table>
132
+ </td>
133
+ </tr>
134
+ </table>
135
+ </div>
136
+ </td>
137
+ </tr>
138
+ </table>
139
+
140
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 32px">
141
+ <tr>
142
+ <td>
143
+ <h3 style="
144
+ font-size: 18px;
145
+ font-weight: 600;
146
+ color: #212529;
147
+ margin: 0 0 16px 0;
148
+ ">
149
+ How to Join Your Session
150
+ </h3>
151
+ <div style="
152
+ background-color: #f8f9fa;
153
+ border-radius: 12px;
154
+ padding: 20px;
155
+ margin-bottom: 20px;
156
+ ">
157
+ <p style="
158
+ font-size: 14px;
159
+ color: #495057;
160
+ margin: 0 0 16px 0;
161
+ line-height: 1.6;
162
+ ">
163
+ <strong>Option 1:</strong> Click the button below to join your video call at the scheduled time.
164
+ </p>
165
+ <table cellspacing="0" cellpadding="0" style="margin: 0 0 20px 0">
166
+ <tr>
167
+ <td style="
168
+ background-color: #f7bd11;
169
+ border-radius: 10px;
170
+ text-align: center;
171
+ ">
172
+ <a href="{{join_link}}" style="
173
+ display: inline-block;
174
+ padding: 14px 32px;
175
+ color: #212529;
176
+ text-decoration: none;
177
+ font-size: 16px;
178
+ font-weight: 600;
179
+ " class="btn-mobile">
180
+ Join Video Call
181
+ </a>
182
+ </td>
183
+ </tr>
184
+ </table>
185
+ <p style="
186
+ font-size: 14px;
187
+ color: #495057;
188
+ margin: 0;
189
+ line-height: 1.6;
190
+ ">
191
+ <strong>Option 2:</strong> Log in to your Spark account and start the session from your dashboard.
192
+ </p>
193
+ </div>
194
+ </td>
195
+ </tr>
196
+ </table>
197
+
198
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
199
+ <tr>
200
+ <td>
201
+ <div style="
202
+ background-color: #fff3cd;
203
+ border-left: 4px solid #ffc107;
204
+ border-radius: 8px;
205
+ padding: 20px;
206
+ ">
207
+ <h4 style="
208
+ font-size: 16px;
209
+ font-weight: 600;
210
+ color: #856404;
211
+ margin: 0 0 12px 0;
212
+ ">
213
+ Cancellation Policy
214
+ </h4>
215
+ <ul style="
216
+ margin: 0;
217
+ padding-left: 20px;
218
+ color: #856404;
219
+ font-size: 14px;
220
+ line-height: 1.8;
221
+ ">
222
+ <li style="margin-bottom: 8px">
223
+ <strong>Free cancellation</strong> up to 48 hours before your session
224
+ </li>
225
+ <li>
226
+ <strong>No refunds</strong> for cancellations made less than 48 hours before the session
227
+ </li>
228
+ </ul>
229
+ </div>
230
+ </td>
231
+ </tr>
232
+ </table>
233
+ </td>
234
+ </tr>
235
+ {% endblock %}
236
+
237
+ {% block after_content %}
238
+ <tr>
239
+ <td style="padding: 24px 40px 32px 40px; text-align: center">
240
+ <p style="
241
+ font-size: 14px;
242
+ font-weight: 400;
243
+ color: #6c757d;
244
+ line-height: 1.6;
245
+ margin: 0 0 8px 0;
246
+ ">
247
+ Have questions about your upcoming session?
248
+ </p>
249
+ <p style="
250
+ font-size: 13px;
251
+ font-weight: 400;
252
+ color: #adb5bd;
253
+ line-height: 1.6;
254
+ margin: 0;
255
+ ">
256
+ We're here to help! Contact us at <a href="mailto:support@spark.com" style="color: #54949D; text-decoration: none; font-weight: 500;">support@spark.com</a>
257
+ </p>
258
+ </td>
259
+ </tr>
260
+ {% endblock %}
cbh/templates/emails/bookingConfirmationCoach.html ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}New Booking - Session with {{user_name}}{% endblock %}
4
+
5
+ {% block main %}
6
+ <tr>
7
+ <td style="padding: 40px 40px 32px 40px">
8
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
9
+ <tr>
10
+ <td style="text-align: center">
11
+ <div style="
12
+ display: inline-block;
13
+ background-color: #fff3cd;
14
+ border-radius: 50%;
15
+ padding: 16px;
16
+ margin: 0 0 24px 0;
17
+ ">
18
+ <div style="
19
+ width: 48px;
20
+ height: 48px;
21
+ background-color: #f7bd11;
22
+ border-radius: 50%;
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ ">
27
+ <span style="color: #212529; font-size: 32px; line-height: 1;">📅</span>
28
+ </div>
29
+ </div>
30
+
31
+ <h1 style="
32
+ font-size: 28px;
33
+ font-weight: 600;
34
+ color: #212529;
35
+ margin: 0 0 12px 0;
36
+ line-height: 1.3;
37
+ ">
38
+ New Session Booked!
39
+ </h1>
40
+
41
+ <p style="
42
+ font-size: 16px;
43
+ color: #6c757d;
44
+ margin: 0 0 32px 0;
45
+ line-height: 1.6;
46
+ ">
47
+ Hi {{coach_name}}, you have a new coaching session scheduled.<br/>
48
+ Get ready to make an impact!
49
+ </p>
50
+ </td>
51
+ </tr>
52
+ </table>
53
+
54
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 32px">
55
+ <tr>
56
+ <td>
57
+ <div style="
58
+ background: linear-gradient(135deg, #54949D 0%, #4a8289 100%);
59
+ border-radius: 12px;
60
+ padding: 24px;
61
+ color: #ffffff;
62
+ ">
63
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
64
+ <tr>
65
+ <td style="padding-bottom: 20px; border-bottom: 1px solid rgba(255, 255, 255, 0.2)">
66
+ <p style="
67
+ font-size: 13px;
68
+ font-weight: 500;
69
+ color: rgba(255, 255, 255, 0.8);
70
+ margin: 0 0 8px 0;
71
+ text-transform: uppercase;
72
+ letter-spacing: 0.5px;
73
+ ">
74
+ Client
75
+ </p>
76
+ <p style="
77
+ font-size: 20px;
78
+ font-weight: 600;
79
+ color: #ffffff;
80
+ margin: 0;
81
+ ">
82
+ {{user_name}}
83
+ </p>
84
+ </td>
85
+ </tr>
86
+ <tr>
87
+ <td style="padding-top: 20px">
88
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
89
+ <tr>
90
+ <td style="width: 50%; vertical-align: top; padding-right: 12px">
91
+ <p style="
92
+ font-size: 13px;
93
+ font-weight: 500;
94
+ color: rgba(255, 255, 255, 0.8);
95
+ margin: 0 0 8px 0;
96
+ text-transform: uppercase;
97
+ letter-spacing: 0.5px;
98
+ ">
99
+ Date & Time
100
+ </p>
101
+ <p style="
102
+ font-size: 16px;
103
+ font-weight: 600;
104
+ color: #ffffff;
105
+ margin: 0;
106
+ ">
107
+ {{start_date}}
108
+ </p>
109
+ </td>
110
+ <td style="width: 50%; vertical-align: top; padding-left: 12px">
111
+ <p style="
112
+ font-size: 13px;
113
+ font-weight: 500;
114
+ color: rgba(255, 255, 255, 0.8);
115
+ margin: 0 0 8px 0;
116
+ text-transform: uppercase;
117
+ letter-spacing: 0.5px;
118
+ ">
119
+ Duration
120
+ </p>
121
+ <p style="
122
+ font-size: 16px;
123
+ font-weight: 600;
124
+ color: #ffffff;
125
+ margin: 0;
126
+ ">
127
+ {{duration}} minutes
128
+ </p>
129
+ </td>
130
+ </tr>
131
+ </table>
132
+ </td>
133
+ </tr>
134
+ </table>
135
+ </div>
136
+ </td>
137
+ </tr>
138
+ </table>
139
+
140
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 32px">
141
+ <tr>
142
+ <td>
143
+ <h3 style="
144
+ font-size: 18px;
145
+ font-weight: 600;
146
+ color: #212529;
147
+ margin: 0 0 16px 0;
148
+ ">
149
+ Ready to Start?
150
+ </h3>
151
+ <div style="
152
+ background-color: #f8f9fa;
153
+ border-radius: 12px;
154
+ padding: 20px;
155
+ margin-bottom: 20px;
156
+ ">
157
+ <p style="
158
+ font-size: 14px;
159
+ color: #495057;
160
+ margin: 0 0 16px 0;
161
+ line-height: 1.6;
162
+ ">
163
+ When it's time for your session, click the button below to join the video call with {{user_name}}.
164
+ </p>
165
+ <table cellspacing="0" cellpadding="0" style="margin: 0">
166
+ <tr>
167
+ <td style="
168
+ background-color: #f7bd11;
169
+ border-radius: 10px;
170
+ text-align: center;
171
+ ">
172
+ <a href="{{join_link}}" style="
173
+ display: inline-block;
174
+ padding: 14px 32px;
175
+ color: #212529;
176
+ text-decoration: none;
177
+ font-size: 16px;
178
+ font-weight: 600;
179
+ " class="btn-mobile">
180
+ Join Video Call
181
+ </a>
182
+ </td>
183
+ </tr>
184
+ </table>
185
+ </div>
186
+ </td>
187
+ </tr>
188
+ </table>
189
+
190
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
191
+ <tr>
192
+ <td>
193
+ <div style="
194
+ background-color: #e7f5ff;
195
+ border-left: 4px solid #54949D;
196
+ border-radius: 8px;
197
+ padding: 20px;
198
+ ">
199
+ <h4 style="
200
+ font-size: 16px;
201
+ font-weight: 600;
202
+ color: #1971c2;
203
+ margin: 0 0 12px 0;
204
+ ">
205
+ Session Tips
206
+ </h4>
207
+ <ul style="
208
+ margin: 0;
209
+ padding-left: 20px;
210
+ color: #1971c2;
211
+ font-size: 14px;
212
+ line-height: 1.8;
213
+ ">
214
+ <li style="margin-bottom: 8px">
215
+ Join 2-3 minutes early to test your audio and video
216
+ </li>
217
+ <li style="margin-bottom: 8px">
218
+ Find a quiet, well-lit space for the best experience
219
+ </li>
220
+ <li>
221
+ Have any relevant notes or materials ready
222
+ </li>
223
+ </ul>
224
+ </div>
225
+ </td>
226
+ </tr>
227
+ </table>
228
+ </td>
229
+ </tr>
230
+ {% endblock %}
231
+
232
+ {% block after_content %}
233
+ <tr>
234
+ <td style="padding: 24px 40px 32px 40px; text-align: center">
235
+ <p style="
236
+ font-size: 14px;
237
+ font-weight: 400;
238
+ color: #6c757d;
239
+ line-height: 1.6;
240
+ margin: 0 0 8px 0;
241
+ ">
242
+ Need to reschedule or have questions?
243
+ </p>
244
+ <p style="
245
+ font-size: 13px;
246
+ font-weight: 400;
247
+ color: #adb5bd;
248
+ line-height: 1.6;
249
+ margin: 0;
250
+ ">
251
+ Contact us at <a href="mailto:support@spark.com" style="color: #54949D; text-decoration: none; font-weight: 500;">support@spark.com</a>
252
+ </p>
253
+ </td>
254
+ </tr>
255
+ {% endblock %}
cbh/templates/emails/confirmEmail.html DELETED
@@ -1,91 +0,0 @@
1
- {% extends "base.html" %}
2
-
3
- {% block title %}Confirm your email{% endblock %}
4
-
5
- {% block main %}
6
- <tr>
7
- <td style="padding: 0 40px 24px 40px">
8
- <table cellspacing="0" cellpadding="0" style="width: 100%">
9
- <tr>
10
- <td>
11
- <table cellspacing="0" cellpadding="0"
12
- style="background-color: #B8E5C5; border-radius: 12px; width: 100%">
13
- <tr>
14
- <td style="padding: 0 8px 8px 0">
15
- <table style="
16
- width: 100%;
17
- border: 1px solid #e4e4e7;
18
- border-radius: 12px;
19
- background-color: #ffffff;
20
- " cellspacing="0" cellpadding="0">
21
- <tr>
22
- <td style="padding: 12px 24px; text-align: center">
23
- <h2 style="
24
- font-size: 18px;
25
- font-weight: 500;
26
- color: #18181b;
27
- line-height: 1.4;
28
- ">
29
- Confirm your email
30
- </h2>
31
-
32
- <p style="
33
- font-size: 14px;
34
- color: #666666;
35
- margin: 0 0 30px 0;
36
- line-height: 1.6;
37
- ">
38
- Hello {{account_name}}, please confirm your email address to complete your
39
- registration.
40
- </p>
41
-
42
- <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
43
- <tr>
44
- <td style="
45
- background-color: #31a152;
46
- border-radius: 8px;
47
- text-align: center;
48
- ">
49
- <a href="{{link}}" style="
50
- display: inline-block;
51
- padding: 8px 80px;
52
- color: #ffffff;
53
- text-decoration: none;
54
- font-size: 15px;
55
- font-weight: 500;
56
- " class="btn-mobile">
57
- Confirm email
58
- </a>
59
- </td>
60
- </tr>
61
- </table>
62
- </td>
63
- </tr>
64
- </table>
65
- </td>
66
- </tr>
67
- </table>
68
- </td>
69
- </tr>
70
- </table>
71
- </td>
72
- </tr>
73
- {% endblock %}
74
-
75
- {% block after_content %}
76
- <tr>
77
- <td style="padding: 5px 20px 40px 20px; text-align: center">
78
- <p style="
79
- font-size: 12px;
80
- font-weight: 500;
81
- color: #71717a;
82
- line-height: 1.6;
83
- margin: 0;
84
- ">
85
- This confirmation link expires in 3 hours. If you didn’t create an account, you can safely ignore this email.
86
- You can always sign in at
87
- <a href="https://{{audience_link}}" style="color: #4ade80; text-decoration: none">{{audience_link}}</a>
88
- </p>
89
- </td>
90
- </tr>
91
- {% endblock %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cbh/templates/emails/createOrg.html DELETED
@@ -1,72 +0,0 @@
1
- {% extends "base.html" %}
2
-
3
- {% block title %}Workspace Invitation{% endblock %}
4
-
5
- {% block main %}
6
- <tr>
7
- <td style="padding: 0 40px 24px 40px">
8
- <table cellspacing="0" cellpadding="0" style="width: 100%">
9
- <tr>
10
- <td>
11
- <table cellspacing="0" cellpadding="0"
12
- style="background-color: #B8E5C5; border-radius: 12px; width: 100%">
13
- <tr>
14
- <td style="padding: 0 8px 8px 0">
15
- <table style="
16
- width: 100%;
17
- border: 1px solid #e4e4e7;
18
- border-radius: 12px;
19
- background-color: #ffffff;
20
- " cellspacing="0" cellpadding="0">
21
- <tr>
22
- <td style="padding: 12px 24px; text-align: center">
23
- <h2 style="
24
- font-size: 18px;
25
- font-weight: 500;
26
- color: #18181b;
27
- line-height: 1.4;
28
- ">
29
- You’ve been invited to Arena
30
- </h2>
31
-
32
- <p style="
33
- font-size: 14px;
34
- color: #666666;
35
- margin: 0 0 30px 0;
36
- line-height: 1.6;
37
- ">
38
- Arena is where you’ll help your team members to get training to get better at sales.
39
- </p>
40
-
41
- <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
42
- <tr>
43
- <td style="
44
- background-color: #31a152;
45
- border-radius: 8px;
46
- text-align: center;
47
- ">
48
- <a href="{{link}}" style="
49
- display: inline-block;
50
- padding: 8px 80px;
51
- color: #ffffff;
52
- text-decoration: none;
53
- font-size: 15px;
54
- font-weight: 500;
55
- " class="btn-mobile">
56
- Create Organization
57
- </a>
58
- </td>
59
- </tr>
60
- </table>
61
- </td>
62
- </tr>
63
- </table>
64
- </td>
65
- </tr>
66
- </table>
67
- </td>
68
- </tr>
69
- </table>
70
- </td>
71
- </tr>
72
- {% endblock %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cbh/templates/emails/inviteToOrg.html DELETED
@@ -1,136 +0,0 @@
1
- {% extends "base.html" %}
2
-
3
- {% block title %}Workspace Invitation{% endblock %}
4
-
5
- {% block main %}
6
- <tr>
7
- <td style="padding: 0 40px 24px 40px">
8
- <table cellspacing="0" cellpadding="0" style="width: 100%">
9
- <tr>
10
- <td>
11
- <table cellspacing="0" cellpadding="0"
12
- style="background-color: #B8E5C5; border-radius: 12px; width: 100%">
13
- <tr>
14
- <td style="padding: 0 8px 8px 0">
15
- <table style="
16
- width: 100%;
17
- border: 1px solid #e4e4e7;
18
- border-radius: 12px;
19
- background-color: #ffffff;
20
- " cellspacing="0" cellpadding="0">
21
- <tr>
22
- <td style="padding: 12px 24px; text-align: center">
23
- <h2 style="
24
- font-size: 18px;
25
- font-weight: 500;
26
- color: #18181b;
27
- line-height: 1.4;
28
- ">
29
- {{admin_name}} has invited to join<br/>
30
- {{organization_name}} in Sales Arena
31
- </h2>
32
-
33
- <p style="
34
- font-size: 14px;
35
- color: #666666;
36
- margin: 0 0 30px 0;
37
- line-height: 1.6;
38
- ">
39
- Sales Arena is where you'll receive training on
40
- you<br/>
41
- next sales pitch. Join {{organization_name}} to get started.
42
- </p>
43
- {% if message %}
44
- <div style="
45
- margin: 0 0 24px 0;
46
- padding: 12px 16px;
47
- border-radius: 10px;
48
- border: 1px solid #e4e4e7;
49
- background-color: #f9fafb;
50
- ">
51
- <p style="
52
- font-size: 14px;
53
- color: #18181b;
54
- margin: 0;
55
- line-height: 1.6;
56
- ">
57
- {{message}}
58
- </p>
59
- </div>
60
- {% endif %}
61
-
62
- <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
63
- <tr>
64
- <td style="
65
- background-color: #31a152;
66
- border-radius: 8px;
67
- text-align: center;
68
- ">
69
- <a href="{{link}}" style="
70
- display: inline-block;
71
- padding: 8px 80px;
72
- color: #ffffff;
73
- text-decoration: none;
74
- font-size: 15px;
75
- font-weight: 500;
76
- " class="btn-mobile">
77
- Join {{organization_name}}
78
- </a>
79
- </td>
80
- </tr>
81
- </table>
82
- <table cellspacing="0" cellpadding="0" style="margin: 10px auto 12px auto">
83
- <tr>
84
- <td style="text-align: center">
85
- <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
86
- <tr>
87
- <td style="vertical-align: middle">
88
- {% if icons %}
89
- <div style="display: inline-block; font-size: 0; line-height: 0; white-space: nowrap">
90
- {% for icon in icons %}
91
- <img src="{{icon}}" style="display: inline-block; vertical-align: middle; width: 24px; height: 24px; border-radius: 50%; border: 2px solid #ffffff; {{ '' if loop.first else 'margin-left: -8px;' }}"/>
92
- {% endfor %}
93
- </div>
94
- {% endif %}
95
- </td>
96
- {% if joins_str %}
97
- <td style="vertical-align: middle; padding-left: 8px">
98
- <span style="font-size: 12px; font-weight: 500; color: #666666">{{joins_str}}</span>
99
- </td>
100
- {% endif %}
101
- </tr>
102
- </table>
103
- </td>
104
- </tr>
105
- </table>
106
- </td>
107
- </tr>
108
- </table>
109
- </td>
110
- </tr>
111
- </table>
112
- </td>
113
- </tr>
114
- </table>
115
- </td>
116
- </tr>
117
- {% endblock %}
118
-
119
- {% block after_content %}
120
- <tr>
121
- <td style="padding: 5px 20px 40px 20px; text-align: center">
122
- <p style="
123
- font-size: 12px;
124
- font-weight: 500;
125
- color: #71717a;
126
- line-height: 1.6;
127
- margin: 0;
128
- ">
129
- This invitation expires in 30 days. Once you join, you can
130
- always access<br/>
131
- your team's workspace, {{organization_name}}, at
132
- <a href="https://{{audience_link}}" style="color: #4ade80; text-decoration: none">{{audience_link}}</a>
133
- </p>
134
- </td>
135
- </tr>
136
- {% endblock %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cbh/templates/emails/inviteToPlayScen.html DELETED
@@ -1,117 +0,0 @@
1
- {% extends "base.html" %}
2
-
3
- {% block title %}Scenario Invitation{% endblock %}
4
-
5
- {% block main %}
6
- <tr>
7
- <td style="padding: 0 40px 24px 40px">
8
- <table cellspacing="0" cellpadding="0" style="width: 100%">
9
- <tr>
10
- <td>
11
- <table cellspacing="0" cellpadding="0"
12
- style="background-color: #B8E5C5; border-radius: 12px; width: 100%">
13
- <tr>
14
- <td style="padding: 0 8px 8px 0">
15
- <table style="
16
- width: 100%;
17
- border: 1px solid #e4e4e7;
18
- border-radius: 12px;
19
- background-color: #ffffff;
20
- " cellspacing="0" cellpadding="0">
21
- <tr>
22
- <td style="padding: 12px 24px; text-align: center">
23
- <h2 style="
24
- font-size: 18px;
25
- font-weight: 500;
26
- color: #18181b;
27
-
28
- line-height: 1.4;
29
- ">
30
- {{admin_name}} has invited to play<br/>
31
- {{scenario_name}}
32
- </h2>
33
-
34
- <p style="
35
- font-size: 14px;
36
- color: #666666;
37
- margin: 0 0 30px 0;
38
- line-height: 1.6;
39
- ">
40
- {{scenario_description}}
41
- </p>
42
-
43
- <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
44
- <tr>
45
- <td style="
46
- background-color: #31a152;
47
- border-radius: 8px;
48
- text-align: center;
49
- ">
50
- <a href="{{link}}" style="
51
- display: inline-block;
52
- padding: 8px 80px;
53
- color: #ffffff;
54
- text-decoration: none;
55
- font-size: 15px;
56
- font-weight: 500;
57
- " class="btn-mobile">
58
- Play scenario
59
- </a>
60
- </td>
61
- </tr>
62
- </table>
63
- <table cellspacing="0" cellpadding="0" style="margin: 10px auto 12px auto">
64
- <tr>
65
- <td style="text-align: center">
66
- <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
67
- <tr>
68
- <td style="vertical-align: middle">
69
- {% if icons %}
70
- <div style="display: inline-block; font-size: 0; line-height: 0; white-space: nowrap">
71
- {% for icon in icons %}
72
- <img src="{{icon}}" style="display: inline-block; vertical-align: middle; width: 24px; height: 24px; border-radius: 50%; border: 2px solid #ffffff; {{ '' if loop.first else 'margin-left: -8px;' }}"/>
73
- {% endfor %}
74
- </div>
75
- {% endif %}
76
- </td>
77
- {% if joins_str %}
78
- <td style="vertical-align: middle; padding-left: 8px">
79
- <span style="font-size: 12px; font-weight: 500; color: #666666">{{joins_str}}</span>
80
- </td>
81
- {% endif %}
82
- </tr>
83
- </table>
84
- </td>
85
- </tr>
86
- </table>
87
- </td>
88
- </tr>
89
- </table>
90
- </td>
91
- </tr>
92
- </table>
93
- </td>
94
- </tr>
95
- </table>
96
- </td>
97
- </tr>
98
- {% endblock %}
99
-
100
- {% block after_content %}
101
- <tr>
102
- <td style="padding: 5px 20px 40px 20px; text-align: center">
103
- <p style="
104
- font-size: 12px;
105
- font-weight: 500;
106
- color: #71717a;
107
- line-height: 1.6;
108
- margin: 0;
109
- ">
110
- This invitation expires in 30 days. Once you join, you can
111
- always access<br/>
112
- your team's workspace, {{organization_name}}, at
113
- <a href="https://{{audience_link}}" style="color: #4ade80; text-decoration: none">{{audience_link}}</a>
114
- </p>
115
- </td>
116
- </tr>
117
- {% endblock %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cbh/templates/emails/resetPassword.html DELETED
@@ -1,114 +0,0 @@
1
- {% extends "base.html" %}
2
-
3
- {% block title %}Reset your password{% endblock %}
4
-
5
- {% block main %}
6
- <tr>
7
- <td style="padding: 0 40px 24px 40px">
8
- <table cellspacing="0" cellpadding="0" style="width: 100%">
9
- <tr>
10
- <td>
11
- <table cellspacing="0" cellpadding="0" style="background-color: #B8E5C5; border-radius: 12px; width: 100%">
12
- <tr>
13
- <td style="padding: 0 8px 8px 0">
14
- <table
15
- style="
16
- width: 100%;
17
- border: 1px solid #e4e4e7;
18
- border-radius: 12px;
19
- background-color: #ffffff;
20
- "
21
- cellspacing="0"
22
- cellpadding="0"
23
- >
24
- <tr>
25
- <td style="padding: 12px 24px; text-align: center">
26
- <h2
27
- style="
28
- font-size: 18px;
29
- font-weight: 500;
30
- color: #18181b;
31
- line-height: 1.4;
32
- "
33
- >
34
- Reset your password
35
- </h2>
36
-
37
- <p
38
- style="
39
- font-size: 14px;
40
- color: #666666;
41
- margin: 0 0 30px 0;
42
- line-height: 1.6;
43
- "
44
- >
45
- A password reset was requested for your Sales Arena account. Click the button below to choose a new password.
46
- </p>
47
-
48
- <table
49
- cellspacing="0"
50
- cellpadding="0"
51
- style="margin: 0 auto"
52
- >
53
- <tr>
54
- <td
55
- style="
56
- background-color: #31a152;
57
- border-radius: 8px;
58
- text-align: center;
59
- "
60
- >
61
- <a
62
- href="{{link}}"
63
- style="
64
- display: inline-block;
65
- padding: 8px 80px;
66
- color: #ffffff;
67
- text-decoration: none;
68
- font-size: 15px;
69
- font-weight: 500;
70
- "
71
- class="btn-mobile"
72
- >
73
- Reset password
74
- </a>
75
- </td>
76
- </tr>
77
- </table>
78
- </td>
79
- </tr>
80
- </table>
81
- </td>
82
- </tr>
83
- </table>
84
- </td>
85
- </tr>
86
- </table>
87
- </td>
88
- </tr>
89
- {% endblock %}
90
-
91
- {% block after_content %}
92
- <tr>
93
- <td style="padding: 5px 20px 40px 20px; text-align: center">
94
- <p
95
- style="
96
- font-size: 12px;
97
- font-weight: 500;
98
- color: #71717a;
99
- line-height: 1.6;
100
- margin: 0;
101
- "
102
- >
103
- This reset link expires in 5 minutes. If you didn’t request a password reset, you can safely ignore this email.
104
- You can always sign in at
105
- <a
106
- href="https://{{audience_link}}"
107
- style="color: #4ade80; text-decoration: none"
108
- >{{audience_link}}</a>
109
- </p>
110
- </td>
111
- </tr>
112
- {% endblock %}
113
-
114
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cbh/templates/emails/scenChangeSug.html DELETED
@@ -1,113 +0,0 @@
1
- {% extends "base.html" %}
2
-
3
- {% block title %}Scenario change suggestion{% endblock %}
4
-
5
- {% block main %}
6
- <tr>
7
- <td style="padding: 0 40px 24px 40px">
8
- <table cellspacing="0" cellpadding="0" style="width: 100%">
9
- <tr>
10
- <td>
11
- <table cellspacing="0" cellpadding="0"
12
- style="background-color: #B8E5C5; border-radius: 12px; width: 100%">
13
- <tr>
14
- <td style="padding: 0 8px 8px 0">
15
- <table style="
16
- width: 100%;
17
- border: 1px solid #e4e4e7;
18
- border-radius: 12px;
19
- background-color: #ffffff;
20
- " cellspacing="0" cellpadding="0">
21
- <tr>
22
- <td style="padding: 12px 24px; text-align: center">
23
- <h2 style="
24
- font-size: 18px;
25
- font-weight: 500;
26
- color: #18181b;
27
- line-height: 1.4;
28
- ">
29
- {{proposed_name}} has suggested changes in {{scenario_name}}
30
- </h2>
31
-
32
- <p style="
33
- font-size: 14px;
34
- color: #666666;
35
- margin: 0 0 30px 0;
36
- line-height: 1.6;
37
- ">
38
- {{proposed_name}} has suggested changes in this scenario.<br>
39
- Please review to make sure you are all aligned.
40
- </p>
41
-
42
- <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
43
- <tr>
44
- <td style="
45
- background-color: #31a152;
46
- border-radius: 8px;
47
- text-align: center;
48
- ">
49
- <a href="{{link}}" style="
50
- display: inline-block;
51
- padding: 8px 80px;
52
- color: #ffffff;
53
- text-decoration: none;
54
- font-size: 15px;
55
- font-weight: 500;
56
- " class="btn-mobile">
57
- Review changes
58
- </a>
59
- </td>
60
- </tr>
61
- </table>
62
- <table cellspacing="0" cellpadding="0" style="margin: 10px auto 12px auto">
63
- <tr>
64
- <td style="text-align: center">
65
- <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
66
- <tr>
67
- <td style="vertical-align: middle">
68
- {% if icons %}
69
- <div style="display: inline-block; font-size: 0; line-height: 0; white-space: nowrap">
70
- {% for icon in icons %}
71
- <img src="{{icon}}" style="display: inline-block; vertical-align: middle; width: 24px; height: 24px; border-radius: 50%; border: 2px solid #ffffff; {{ '' if loop.first else 'margin-left: -8px;' }}"/>
72
- {% endfor %}
73
- </div>
74
- {% endif %}
75
- </td>
76
- {% if joins_str %}
77
- <td style="vertical-align: middle; padding-left: 8px">
78
- <span style="font-size: 12px; font-weight: 500; color: #666666">{{joins_str}}</span>
79
- </td>
80
- {% endif %}
81
- </tr>
82
- </table>
83
- </td>
84
- </tr>
85
- </table>
86
- </td>
87
- </tr>
88
- </table>
89
- </td>
90
- </tr>
91
- </table>
92
- </td>
93
- </tr>
94
- </table>
95
- </td>
96
- </tr>
97
- {% endblock %}
98
-
99
- {% block after_content %}
100
- <tr>
101
- <td style="padding: 5px 20px 40px 20px; text-align: center">
102
- <p style="
103
- font-size: 12px;
104
- font-weight: 500;
105
- color: #71717a;
106
- line-height: 1.6;
107
- margin: 0;
108
- ">
109
- If you decide to ignore this message, your scenario will remain as is.
110
- </p>
111
- </td>
112
- </tr>
113
- {% endblock %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cbh/templates/emails/sessionCancellation.html ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}Session Cancelled{% endblock %}
4
+
5
+ {% block main %}
6
+ <tr>
7
+ <td style="padding: 40px 40px 32px 40px">
8
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
9
+ <tr>
10
+ <td style="text-align: center">
11
+ <div style="
12
+ display: inline-block;
13
+ background-color: #fff3cd;
14
+ border-radius: 50%;
15
+ padding: 16px;
16
+ margin: 0 0 24px 0;
17
+ ">
18
+ <div style="
19
+ width: 48px;
20
+ height: 48px;
21
+ background-color: #6c757d;
22
+ border-radius: 50%;
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ ">
27
+ <span style="color: #ffffff; font-size: 32px; line-height: 1;">✕</span>
28
+ </div>
29
+ </div>
30
+
31
+ <h1 style="
32
+ font-size: 28px;
33
+ font-weight: 600;
34
+ color: #212529;
35
+ margin: 0 0 12px 0;
36
+ line-height: 1.3;
37
+ ">
38
+ Session Cancelled
39
+ </h1>
40
+
41
+ <p style="
42
+ font-size: 16px;
43
+ color: #6c757d;
44
+ margin: 0 0 32px 0;
45
+ line-height: 1.6;
46
+ ">
47
+ Hi {{user_name}}, your coaching session has been successfully cancelled.
48
+ </p>
49
+ </td>
50
+ </tr>
51
+ </table>
52
+
53
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 32px">
54
+ <tr>
55
+ <td>
56
+ <div style="
57
+ background-color: #f8f9fa;
58
+ border: 1px solid #dee2e6;
59
+ border-radius: 12px;
60
+ padding: 24px;
61
+ ">
62
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
63
+ <tr>
64
+ <td style="padding-bottom: 16px; border-bottom: 1px solid #dee2e6">
65
+ <p style="
66
+ font-size: 12px;
67
+ font-weight: 600;
68
+ color: #6c757d;
69
+ margin: 0 0 6px 0;
70
+ text-transform: uppercase;
71
+ letter-spacing: 0.5px;
72
+ ">
73
+ Cancelled Session
74
+ </p>
75
+ <p style="
76
+ font-size: 18px;
77
+ font-weight: 600;
78
+ color: #212529;
79
+ margin: 0;
80
+ ">
81
+ {{coach_name}}
82
+ </p>
83
+ </td>
84
+ </tr>
85
+ <tr>
86
+ <td style="padding-top: 16px">
87
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
88
+ <tr>
89
+ <td style="width: 50%; vertical-align: top; padding-right: 12px">
90
+ <p style="
91
+ font-size: 12px;
92
+ font-weight: 600;
93
+ color: #6c757d;
94
+ margin: 0 0 6px 0;
95
+ text-transform: uppercase;
96
+ letter-spacing: 0.5px;
97
+ ">
98
+ Scheduled For
99
+ </p>
100
+ <p style="
101
+ font-size: 15px;
102
+ font-weight: 500;
103
+ color: #495057;
104
+ margin: 0;
105
+ ">
106
+ {{start_date}}
107
+ </p>
108
+ </td>
109
+ <td style="width: 50%; vertical-align: top; padding-left: 12px">
110
+ <p style="
111
+ font-size: 12px;
112
+ font-weight: 600;
113
+ color: #6c757d;
114
+ margin: 0 0 6px 0;
115
+ text-transform: uppercase;
116
+ letter-spacing: 0.5px;
117
+ ">
118
+ Duration
119
+ </p>
120
+ <p style="
121
+ font-size: 15px;
122
+ font-weight: 500;
123
+ color: #495057;
124
+ margin: 0;
125
+ ">
126
+ {{duration}} minutes
127
+ </p>
128
+ </td>
129
+ </tr>
130
+ </table>
131
+ </td>
132
+ </tr>
133
+ </table>
134
+ </div>
135
+ </td>
136
+ </tr>
137
+ </table>
138
+
139
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 24px">
140
+ <tr>
141
+ <td>
142
+ <div style="
143
+ background-color: #d1ecf1;
144
+ border-left: 4px solid #0c5460;
145
+ border-radius: 8px;
146
+ padding: 20px;
147
+ ">
148
+ <h4 style="
149
+ font-size: 16px;
150
+ font-weight: 600;
151
+ color: #0c5460;
152
+ margin: 0 0 12px 0;
153
+ ">
154
+ Refund Information
155
+ </h4>
156
+ <p style="
157
+ margin: 0;
158
+ color: #0c5460;
159
+ font-size: 14px;
160
+ line-height: 1.7;
161
+ ">
162
+ Your payment has been refunded. The funds will appear in your account within <strong>5 business days</strong>, depending on your payment provider.
163
+ </p>
164
+ </div>
165
+ </td>
166
+ </tr>
167
+ </table>
168
+
169
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
170
+ <tr>
171
+ <td style="text-align: center">
172
+ <p style="
173
+ font-size: 16px;
174
+ font-weight: 500;
175
+ color: #495057;
176
+ margin: 0 0 20px 0;
177
+ line-height: 1.6;
178
+ ">
179
+ We're here whenever you're ready to book again.
180
+ </p>
181
+ <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
182
+ <tr>
183
+ <td style="
184
+ background-color: #f7bd11;
185
+ border-radius: 10px;
186
+ text-align: center;
187
+ ">
188
+ <a href="https://spark.com/coaches" style="
189
+ display: inline-block;
190
+ padding: 14px 32px;
191
+ color: #212529;
192
+ text-decoration: none;
193
+ font-size: 16px;
194
+ font-weight: 600;
195
+ " class="btn-mobile">
196
+ Browse Coaches
197
+ </a>
198
+ </td>
199
+ </tr>
200
+ </table>
201
+ </td>
202
+ </tr>
203
+ </table>
204
+ </td>
205
+ </tr>
206
+ {% endblock %}
207
+
208
+ {% block after_content %}
209
+ <tr>
210
+ <td style="padding: 24px 40px 32px 40px; text-align: center">
211
+ <p style="
212
+ font-size: 13px;
213
+ font-weight: 400;
214
+ color: #6c757d;
215
+ line-height: 1.6;
216
+ margin: 0;
217
+ ">
218
+ Questions about your refund or cancellation?<br/>
219
+ Contact us at <a href="mailto:support@spark.com" style="color: #54949D; text-decoration: none; font-weight: 500;">support@spark.com</a>
220
+ </p>
221
+ </td>
222
+ </tr>
223
+ {% endblock %}
cbh/templates/emails/sessionCancellationCoach.html ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}Session Cancelled{% endblock %}
4
+
5
+ {% block main %}
6
+ <tr>
7
+ <td style="padding: 40px 40px 32px 40px">
8
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
9
+ <tr>
10
+ <td style="text-align: center">
11
+ <div style="
12
+ display: inline-block;
13
+ background-color: #fff3cd;
14
+ border-radius: 50%;
15
+ padding: 16px;
16
+ margin: 0 0 24px 0;
17
+ ">
18
+ <div style="
19
+ width: 48px;
20
+ height: 48px;
21
+ background-color: #6c757d;
22
+ border-radius: 50%;
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ ">
27
+ <span style="color: #ffffff; font-size: 32px; line-height: 1;">✕</span>
28
+ </div>
29
+ </div>
30
+
31
+ <h1 style="
32
+ font-size: 28px;
33
+ font-weight: 600;
34
+ color: #212529;
35
+ margin: 0 0 12px 0;
36
+ line-height: 1.3;
37
+ ">
38
+ Session Cancelled
39
+ </h1>
40
+
41
+ <p style="
42
+ font-size: 16px;
43
+ color: #6c757d;
44
+ margin: 0 0 32px 0;
45
+ line-height: 1.6;
46
+ ">
47
+ Hi {{coach_name}}, your scheduled session with {{user_name}}<br/>
48
+ has been cancelled by the client.
49
+ </p>
50
+ </td>
51
+ </tr>
52
+ </table>
53
+
54
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 32px">
55
+ <tr>
56
+ <td>
57
+ <div style="
58
+ background-color: #f8f9fa;
59
+ border: 1px solid #dee2e6;
60
+ border-radius: 12px;
61
+ padding: 24px;
62
+ ">
63
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
64
+ <tr>
65
+ <td style="padding-bottom: 16px; border-bottom: 1px solid #dee2e6">
66
+ <p style="
67
+ font-size: 12px;
68
+ font-weight: 600;
69
+ color: #6c757d;
70
+ margin: 0 0 6px 0;
71
+ text-transform: uppercase;
72
+ letter-spacing: 0.5px;
73
+ ">
74
+ Cancelled Session
75
+ </p>
76
+ <p style="
77
+ font-size: 18px;
78
+ font-weight: 600;
79
+ color: #212529;
80
+ margin: 0;
81
+ ">
82
+ {{user_name}}
83
+ </p>
84
+ </td>
85
+ </tr>
86
+ <tr>
87
+ <td style="padding-top: 16px">
88
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
89
+ <tr>
90
+ <td style="width: 50%; vertical-align: top; padding-right: 12px">
91
+ <p style="
92
+ font-size: 12px;
93
+ font-weight: 600;
94
+ color: #6c757d;
95
+ margin: 0 0 6px 0;
96
+ text-transform: uppercase;
97
+ letter-spacing: 0.5px;
98
+ ">
99
+ Was Scheduled For
100
+ </p>
101
+ <p style="
102
+ font-size: 15px;
103
+ font-weight: 500;
104
+ color: #495057;
105
+ margin: 0;
106
+ ">
107
+ {{start_date}}
108
+ </p>
109
+ </td>
110
+ <td style="width: 50%; vertical-align: top; padding-left: 12px">
111
+ <p style="
112
+ font-size: 12px;
113
+ font-weight: 600;
114
+ color: #6c757d;
115
+ margin: 0 0 6px 0;
116
+ text-transform: uppercase;
117
+ letter-spacing: 0.5px;
118
+ ">
119
+ Duration
120
+ </p>
121
+ <p style="
122
+ font-size: 15px;
123
+ font-weight: 500;
124
+ color: #495057;
125
+ margin: 0;
126
+ ">
127
+ {{duration}} minutes
128
+ </p>
129
+ </td>
130
+ </tr>
131
+ </table>
132
+ </td>
133
+ </tr>
134
+ </table>
135
+ </div>
136
+ </td>
137
+ </tr>
138
+ </table>
139
+
140
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 24px">
141
+ <tr>
142
+ <td>
143
+ <div style="
144
+ background-color: #e7f5ff;
145
+ border-left: 4px solid #54949D;
146
+ border-radius: 8px;
147
+ padding: 20px;
148
+ ">
149
+ <p style="
150
+ margin: 0;
151
+ color: #1971c2;
152
+ font-size: 14px;
153
+ line-height: 1.7;
154
+ ">
155
+ This time slot is now available in your calendar. Your schedule has been automatically updated to reflect this change.
156
+ </p>
157
+ </div>
158
+ </td>
159
+ </tr>
160
+ </table>
161
+
162
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
163
+ <tr>
164
+ <td style="text-align: center">
165
+ <p style="
166
+ font-size: 16px;
167
+ font-weight: 500;
168
+ color: #495057;
169
+ margin: 0 0 20px 0;
170
+ line-height: 1.6;
171
+ ">
172
+ Check your dashboard for upcoming sessions.
173
+ </p>
174
+ <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
175
+ <tr>
176
+ <td style="
177
+ background-color: #f7bd11;
178
+ border-radius: 10px;
179
+ text-align: center;
180
+ ">
181
+ <a href="https://spark.com/coach/dashboard" style="
182
+ display: inline-block;
183
+ padding: 14px 32px;
184
+ color: #212529;
185
+ text-decoration: none;
186
+ font-size: 16px;
187
+ font-weight: 600;
188
+ " class="btn-mobile">
189
+ View Dashboard
190
+ </a>
191
+ </td>
192
+ </tr>
193
+ </table>
194
+ </td>
195
+ </tr>
196
+ </table>
197
+ </td>
198
+ </tr>
199
+ {% endblock %}
200
+
201
+ {% block after_content %}
202
+ <tr>
203
+ <td style="padding: 24px 40px 32px 40px; text-align: center">
204
+ <p style="
205
+ font-size: 13px;
206
+ font-weight: 400;
207
+ color: #6c757d;
208
+ line-height: 1.6;
209
+ margin: 0;
210
+ ">
211
+ Questions about this cancellation?<br/>
212
+ Contact us at <a href="mailto:support@spark.com" style="color: #54949D; text-decoration: none; font-weight: 500;">support@spark.com</a>
213
+ </p>
214
+ </td>
215
+ </tr>
216
+ {% endblock %}
cbh/templates/emails/sessionReminder.html ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}Reminder: Your Session Starts Soon{% endblock %}
4
+
5
+ {% block main %}
6
+ <tr>
7
+ <td style="padding: 40px 40px 32px 40px">
8
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
9
+ <tr>
10
+ <td style="text-align: center">
11
+ <div style="
12
+ display: inline-block;
13
+ background-color: #fff3cd;
14
+ border-radius: 50%;
15
+ padding: 16px;
16
+ margin: 0 0 24px 0;
17
+ ">
18
+ <div style="
19
+ width: 48px;
20
+ height: 48px;
21
+ background-color: #ffc107;
22
+ border-radius: 50%;
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ ">
27
+ <span style="color: #212529; font-size: 32px; line-height: 1;">⏰</span>
28
+ </div>
29
+ </div>
30
+
31
+ <h1 style="
32
+ font-size: 28px;
33
+ font-weight: 600;
34
+ color: #212529;
35
+ margin: 0 0 12px 0;
36
+ line-height: 1.3;
37
+ ">
38
+ Your Session Starts in 1 Hour
39
+ </h1>
40
+
41
+ <p style="
42
+ font-size: 16px;
43
+ color: #6c757d;
44
+ margin: 0 0 32px 0;
45
+ line-height: 1.6;
46
+ ">
47
+ Hi {{user_name}}, this is a friendly reminder about your upcoming<br/>
48
+ coaching session with {{coach_name}}.
49
+ </p>
50
+ </td>
51
+ </tr>
52
+ </table>
53
+
54
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 32px">
55
+ <tr>
56
+ <td>
57
+ <div style="
58
+ background: linear-gradient(135deg, #54949D 0%, #4a8289 100%);
59
+ border-radius: 12px;
60
+ padding: 24px;
61
+ color: #ffffff;
62
+ ">
63
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
64
+ <tr>
65
+ <td style="padding-bottom: 20px; border-bottom: 1px solid rgba(255, 255, 255, 0.2)">
66
+ <p style="
67
+ font-size: 13px;
68
+ font-weight: 500;
69
+ color: rgba(255, 255, 255, 0.8);
70
+ margin: 0 0 8px 0;
71
+ text-transform: uppercase;
72
+ letter-spacing: 0.5px;
73
+ ">
74
+ Your Coach
75
+ </p>
76
+ <p style="
77
+ font-size: 20px;
78
+ font-weight: 600;
79
+ color: #ffffff;
80
+ margin: 0;
81
+ ">
82
+ {{coach_name}}
83
+ </p>
84
+ </td>
85
+ </tr>
86
+ <tr>
87
+ <td style="padding-top: 20px">
88
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
89
+ <tr>
90
+ <td style="width: 50%; vertical-align: top; padding-right: 12px">
91
+ <p style="
92
+ font-size: 13px;
93
+ font-weight: 500;
94
+ color: rgba(255, 255, 255, 0.8);
95
+ margin: 0 0 8px 0;
96
+ text-transform: uppercase;
97
+ letter-spacing: 0.5px;
98
+ ">
99
+ Start Time
100
+ </p>
101
+ <p style="
102
+ font-size: 16px;
103
+ font-weight: 600;
104
+ color: #ffffff;
105
+ margin: 0;
106
+ ">
107
+ {{start_date}}
108
+ </p>
109
+ </td>
110
+ <td style="width: 50%; vertical-align: top; padding-left: 12px">
111
+ <p style="
112
+ font-size: 13px;
113
+ font-weight: 500;
114
+ color: rgba(255, 255, 255, 0.8);
115
+ margin: 0 0 8px 0;
116
+ text-transform: uppercase;
117
+ letter-spacing: 0.5px;
118
+ ">
119
+ Duration
120
+ </p>
121
+ <p style="
122
+ font-size: 16px;
123
+ font-weight: 600;
124
+ color: #ffffff;
125
+ margin: 0;
126
+ ">
127
+ {{duration}} minutes
128
+ </p>
129
+ </td>
130
+ </tr>
131
+ </table>
132
+ </td>
133
+ </tr>
134
+ </table>
135
+ </div>
136
+ </td>
137
+ </tr>
138
+ </table>
139
+
140
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 24px">
141
+ <tr>
142
+ <td style="text-align: center">
143
+ <p style="
144
+ font-size: 16px;
145
+ font-weight: 600;
146
+ color: #212529;
147
+ margin: 0 0 16px 0;
148
+ ">
149
+ Ready to join? Click the button below
150
+ </p>
151
+ <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
152
+ <tr>
153
+ <td style="
154
+ background-color: #f7bd11;
155
+ border-radius: 10px;
156
+ text-align: center;
157
+ ">
158
+ <a href="{{join_link}}" style="
159
+ display: inline-block;
160
+ padding: 16px 48px;
161
+ color: #212529;
162
+ text-decoration: none;
163
+ font-size: 18px;
164
+ font-weight: 600;
165
+ " class="btn-mobile">
166
+ Join Video Call
167
+ </a>
168
+ </td>
169
+ </tr>
170
+ </table>
171
+ </td>
172
+ </tr>
173
+ </table>
174
+
175
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
176
+ <tr>
177
+ <td>
178
+ <div style="
179
+ background-color: #e7f5ff;
180
+ border-left: 4px solid #54949D;
181
+ border-radius: 8px;
182
+ padding: 20px;
183
+ ">
184
+ <h4 style="
185
+ font-size: 15px;
186
+ font-weight: 600;
187
+ color: #1971c2;
188
+ margin: 0 0 10px 0;
189
+ ">
190
+ Quick Tips
191
+ </h4>
192
+ <ul style="
193
+ margin: 0;
194
+ padding-left: 20px;
195
+ color: #1971c2;
196
+ font-size: 14px;
197
+ line-height: 1.7;
198
+ ">
199
+ <li style="margin-bottom: 6px">
200
+ Test your camera and microphone before joining
201
+ </li>
202
+ <li style="margin-bottom: 6px">
203
+ Find a quiet space with good lighting
204
+ </li>
205
+ <li>
206
+ Have a notebook ready for key takeaways
207
+ </li>
208
+ </ul>
209
+ </div>
210
+ </td>
211
+ </tr>
212
+ </table>
213
+ </td>
214
+ </tr>
215
+ {% endblock %}
216
+
217
+ {% block after_content %}
218
+ <tr>
219
+ <td style="padding: 24px 40px 32px 40px; text-align: center">
220
+ <p style="
221
+ font-size: 13px;
222
+ font-weight: 400;
223
+ color: #6c757d;
224
+ line-height: 1.6;
225
+ margin: 0;
226
+ ">
227
+ See you soon! If you have any issues joining, contact us at<br/>
228
+ <a href="mailto:support@spark.com" style="color: #54949D; text-decoration: none; font-weight: 500;">support@spark.com</a>
229
+ </p>
230
+ </td>
231
+ </tr>
232
+ {% endblock %}
cbh/templates/emails/sessionReminderCoach.html ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}Reminder: Your Session Starts Soon{% endblock %}
4
+
5
+ {% block main %}
6
+ <tr>
7
+ <td style="padding: 40px 40px 32px 40px">
8
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
9
+ <tr>
10
+ <td style="text-align: center">
11
+ <div style="
12
+ display: inline-block;
13
+ background-color: #fff3cd;
14
+ border-radius: 50%;
15
+ padding: 16px;
16
+ margin: 0 0 24px 0;
17
+ ">
18
+ <div style="
19
+ width: 48px;
20
+ height: 48px;
21
+ background-color: #ffc107;
22
+ border-radius: 50%;
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ ">
27
+ <span style="color: #212529; font-size: 32px; line-height: 1;">⏰</span>
28
+ </div>
29
+ </div>
30
+
31
+ <h1 style="
32
+ font-size: 28px;
33
+ font-weight: 600;
34
+ color: #212529;
35
+ margin: 0 0 12px 0;
36
+ line-height: 1.3;
37
+ ">
38
+ Your Session Starts in 1 Hour
39
+ </h1>
40
+
41
+ <p style="
42
+ font-size: 16px;
43
+ color: #6c757d;
44
+ margin: 0 0 32px 0;
45
+ line-height: 1.6;
46
+ ">
47
+ Hi {{coach_name}}, this is a friendly reminder about your upcoming<br/>
48
+ coaching session with {{user_name}}.
49
+ </p>
50
+ </td>
51
+ </tr>
52
+ </table>
53
+
54
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 32px">
55
+ <tr>
56
+ <td>
57
+ <div style="
58
+ background: linear-gradient(135deg, #54949D 0%, #4a8289 100%);
59
+ border-radius: 12px;
60
+ padding: 24px;
61
+ color: #ffffff;
62
+ ">
63
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
64
+ <tr>
65
+ <td style="padding-bottom: 20px; border-bottom: 1px solid rgba(255, 255, 255, 0.2)">
66
+ <p style="
67
+ font-size: 13px;
68
+ font-weight: 500;
69
+ color: rgba(255, 255, 255, 0.8);
70
+ margin: 0 0 8px 0;
71
+ text-transform: uppercase;
72
+ letter-spacing: 0.5px;
73
+ ">
74
+ Your Client
75
+ </p>
76
+ <p style="
77
+ font-size: 20px;
78
+ font-weight: 600;
79
+ color: #ffffff;
80
+ margin: 0;
81
+ ">
82
+ {{user_name}}
83
+ </p>
84
+ </td>
85
+ </tr>
86
+ <tr>
87
+ <td style="padding-top: 20px">
88
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
89
+ <tr>
90
+ <td style="width: 50%; vertical-align: top; padding-right: 12px">
91
+ <p style="
92
+ font-size: 13px;
93
+ font-weight: 500;
94
+ color: rgba(255, 255, 255, 0.8);
95
+ margin: 0 0 8px 0;
96
+ text-transform: uppercase;
97
+ letter-spacing: 0.5px;
98
+ ">
99
+ Start Time
100
+ </p>
101
+ <p style="
102
+ font-size: 16px;
103
+ font-weight: 600;
104
+ color: #ffffff;
105
+ margin: 0;
106
+ ">
107
+ {{start_date}}
108
+ </p>
109
+ </td>
110
+ <td style="width: 50%; vertical-align: top; padding-left: 12px">
111
+ <p style="
112
+ font-size: 13px;
113
+ font-weight: 500;
114
+ color: rgba(255, 255, 255, 0.8);
115
+ margin: 0 0 8px 0;
116
+ text-transform: uppercase;
117
+ letter-spacing: 0.5px;
118
+ ">
119
+ Duration
120
+ </p>
121
+ <p style="
122
+ font-size: 16px;
123
+ font-weight: 600;
124
+ color: #ffffff;
125
+ margin: 0;
126
+ ">
127
+ {{duration}} minutes
128
+ </p>
129
+ </td>
130
+ </tr>
131
+ </table>
132
+ </td>
133
+ </tr>
134
+ </table>
135
+ </div>
136
+ </td>
137
+ </tr>
138
+ </table>
139
+
140
+ <table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 24px">
141
+ <tr>
142
+ <td style="text-align: center">
143
+ <p style="
144
+ font-size: 16px;
145
+ font-weight: 600;
146
+ color: #212529;
147
+ margin: 0 0 16px 0;
148
+ ">
149
+ Time to get ready! Join when you're set
150
+ </p>
151
+ <table cellspacing="0" cellpadding="0" style="margin: 0 auto">
152
+ <tr>
153
+ <td style="
154
+ background-color: #f7bd11;
155
+ border-radius: 10px;
156
+ text-align: center;
157
+ ">
158
+ <a href="{{join_link}}" style="
159
+ display: inline-block;
160
+ padding: 16px 48px;
161
+ color: #212529;
162
+ text-decoration: none;
163
+ font-size: 18px;
164
+ font-weight: 600;
165
+ " class="btn-mobile">
166
+ Join Video Call
167
+ </a>
168
+ </td>
169
+ </tr>
170
+ </table>
171
+ </td>
172
+ </tr>
173
+ </table>
174
+
175
+ <table cellspacing="0" cellpadding="0" style="width: 100%">
176
+ <tr>
177
+ <td>
178
+ <div style="
179
+ background-color: #e7f5ff;
180
+ border-left: 4px solid #54949D;
181
+ border-radius: 8px;
182
+ padding: 20px;
183
+ ">
184
+ <h4 style="
185
+ font-size: 15px;
186
+ font-weight: 600;
187
+ color: #1971c2;
188
+ margin: 0 0 10px 0;
189
+ ">
190
+ Pre-Session Checklist
191
+ </h4>
192
+ <ul style="
193
+ margin: 0;
194
+ padding-left: 20px;
195
+ color: #1971c2;
196
+ font-size: 14px;
197
+ line-height: 1.7;
198
+ ">
199
+ <li style="margin-bottom: 6px">
200
+ Review any client notes or previous session summaries
201
+ </li>
202
+ <li style="margin-bottom: 6px">
203
+ Ensure your environment is quiet and professional
204
+ </li>
205
+ <li>
206
+ Test your audio and video equipment
207
+ </li>
208
+ </ul>
209
+ </div>
210
+ </td>
211
+ </tr>
212
+ </table>
213
+ </td>
214
+ </tr>
215
+ {% endblock %}
216
+
217
+ {% block after_content %}
218
+ <tr>
219
+ <td style="padding: 24px 40px 32px 40px; text-align: center">
220
+ <p style="
221
+ font-size: 13px;
222
+ font-weight: 400;
223
+ color: #6c757d;
224
+ line-height: 1.6;
225
+ margin: 0;
226
+ ">
227
+ Looking forward to a great session! Need assistance?<br/>
228
+ <a href="mailto:support@spark.com" style="color: #54949D; text-decoration: none; font-weight: 500;">support@spark.com</a>
229
+ </p>
230
+ </td>
231
+ </tr>
232
+ {% endblock %}