Nikolay Angelov commited on
Commit
3b3fbd6
·
1 Parent(s): 50ba800

add google analytics

Browse files
README.md CHANGED
@@ -6,7 +6,7 @@ colorTo: indigo
6
  sdk: docker
7
  app_port: 8000
8
  python_version: 3.12.3
9
- short_description: "AI career coach powered by Llama-3.3-70B"
10
  tags:
11
  - career
12
  - ai
 
6
  sdk: docker
7
  app_port: 8000
8
  python_version: 3.12.3
9
+ short_description: "AI career coach powered by Llama-3.3-70B-Instruct"
10
  tags:
11
  - career
12
  - ai
app.py CHANGED
@@ -48,6 +48,7 @@ app.add_middleware(
48
  if not os.getenv('HUGGINGFACEHUB_API_TOKEN'):
49
  raise ValueError("Please set HUGGINGFACEHUB_API_TOKEN environment variable")
50
 
 
51
  model = "meta-llama/Llama-3.3-70B-Instruct"
52
 
53
  # Initialize the HuggingFace pipeline with more strict parameters
 
48
  if not os.getenv('HUGGINGFACEHUB_API_TOKEN'):
49
  raise ValueError("Please set HUGGINGFACEHUB_API_TOKEN environment variable")
50
 
51
+ #model = "nvidia/Llama-3.1-Nemotron-70B-Instruct-HF"
52
  model = "meta-llama/Llama-3.3-70B-Instruct"
53
 
54
  # Initialize the HuggingFace pipeline with more strict parameters
frontend/public/index.html CHANGED
@@ -2,17 +2,39 @@
2
  <html lang="en">
3
  <head>
4
  <meta charset="utf-8" />
 
 
 
 
 
 
 
 
 
 
 
5
  <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
7
  <meta name="theme-color" content="#000000" />
8
  <meta
9
  name="description"
10
- content="AI CareerCoach - Your personal career development assistant"
11
  />
 
 
 
 
 
 
 
 
12
  <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
13
- <title>AI CareerCoach</title>
 
 
14
  </head>
15
  <body>
 
16
  <noscript>You need to enable JavaScript to run this app.</noscript>
17
  <div id="root"></div>
18
  </body>
 
2
  <html lang="en">
3
  <head>
4
  <meta charset="utf-8" />
5
+
6
+ <!-- Google tag (gtag.js) -->
7
+ <script async src="https://www.googletagmanager.com/gtag/js?id=G-MMXJ7F6PTQ"></script>
8
+ <script>
9
+ window.dataLayer = window.dataLayer || [];
10
+ function gtag(){dataLayer.push(arguments);}
11
+ gtag('js', new Date());
12
+
13
+ gtag('config', 'G-MMXJ7F6PTQ');
14
+ </script>
15
+
16
  <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
17
  <meta name="viewport" content="width=device-width, initial-scale=1" />
18
  <meta name="theme-color" content="#000000" />
19
  <meta
20
  name="description"
21
+ content="AI CareerCoach - Your personal career development assistant powered by artificial intelligence. Get personalized career guidance, job search assistance, and professional development advice."
22
  />
23
+ <meta name="keywords" content="AI career coach, career development, job search, professional guidance, career advice, AI assistant" />
24
+ <meta name="author" content="AI CareerCoach" />
25
+ <meta name="robots" content="index, follow" />
26
+ <meta property="og:title" content="AI CareerCoach - Your Personal Career Development Assistant" />
27
+ <meta property="og:description" content="Get personalized career guidance and professional development advice powered by AI." />
28
+ <meta property="og:type" content="website" />
29
+ <meta property="og:url" content="%PUBLIC_URL%" />
30
+ <meta name="twitter:card" content="summary_large_image" />
31
  <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
32
+ <title>AI CareerCoach - Your Personal Career Development Assistant</title>
33
+
34
+
35
  </head>
36
  <body>
37
+
38
  <noscript>You need to enable JavaScript to run this app.</noscript>
39
  <div id="root"></div>
40
  </body>
frontend/src/components/ChatFooter.tsx CHANGED
@@ -1,6 +1,13 @@
1
  import React from 'react';
2
  import styled from 'styled-components';
3
 
 
 
 
 
 
 
 
4
  const FooterContainer = styled.div`
5
  display: flex;
6
  justify-content: space-around;
@@ -41,16 +48,27 @@ interface ChatFooterProps {
41
  }
42
 
43
  const ChatFooter: React.FC<ChatFooterProps> = ({ onOpenFeedback, onOpenPDP }) => {
 
 
 
 
 
 
 
 
 
 
 
44
  return (
45
  <FooterContainer>
46
  <FeedbackButton onClick={onOpenFeedback}>
47
  Send Feedback
48
  </FeedbackButton>
49
- <PDPButton onClick={onOpenPDP}>
50
  Generate Personal Development Plan
51
  </PDPButton>
52
  </FooterContainer>
53
  );
54
  };
55
 
56
- export default ChatFooter;
 
1
  import React from 'react';
2
  import styled from 'styled-components';
3
 
4
+ // Declare gtag on the Window object to resolve TypeScript error
5
+ declare global {
6
+ interface Window {
7
+ gtag?: (...args: any[]) => void;
8
+ }
9
+ }
10
+
11
  const FooterContainer = styled.div`
12
  display: flex;
13
  justify-content: space-around;
 
48
  }
49
 
50
  const ChatFooter: React.FC<ChatFooterProps> = ({ onOpenFeedback, onOpenPDP }) => {
51
+ const handlePDPButtonClick = () => {
52
+ if (window.gtag) {
53
+ window.gtag('event', 'click', {
54
+ event_category: 'ChatFooter',
55
+ event_label: 'PDPButton',
56
+ value: 1,
57
+ });
58
+ }
59
+ onOpenPDP();
60
+ };
61
+
62
  return (
63
  <FooterContainer>
64
  <FeedbackButton onClick={onOpenFeedback}>
65
  Send Feedback
66
  </FeedbackButton>
67
+ <PDPButton onClick={handlePDPButtonClick}>
68
  Generate Personal Development Plan
69
  </PDPButton>
70
  </FooterContainer>
71
  );
72
  };
73
 
74
+ export default ChatFooter;
frontend/src/components/PDPDialog.tsx CHANGED
@@ -1,6 +1,13 @@
1
- import React, { useState } from 'react';
2
  import styled from 'styled-components';
3
 
 
 
 
 
 
 
 
4
  const DialogOverlay = styled.div`
5
  position: fixed;
6
  top: 0;
@@ -176,7 +183,7 @@ export interface PDPFormData {
176
  targetDate: string;
177
  }
178
 
179
- const PDPDialog: React.FC<PDPDialogProps> = ({ isOpen, onClose, onSubmit }) => {
180
  const [formData, setFormData] = useState<PDPFormData>({
181
  cvFile: null,
182
  careerGoal: '',
@@ -188,28 +195,28 @@ const PDPDialog: React.FC<PDPDialogProps> = ({ isOpen, onClose, onSubmit }) => {
188
 
189
  if (!isOpen) return null;
190
 
191
- const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
192
  const file = event.target.files?.[0];
193
  if (file && file.type === 'application/pdf') {
194
- setFormData(prev => ({ ...prev, cvFile: file }));
195
  } else {
196
  alert('Please select a PDF file');
197
  }
198
  };
199
 
200
- const handleDrop = (event: React.DragEvent) => {
201
  event.preventDefault();
202
  setDragOver(false);
203
 
204
  const file = event.dataTransfer.files[0];
205
  if (file && file.type === 'application/pdf') {
206
- setFormData(prev => ({ ...prev, cvFile: file }));
207
  } else {
208
  alert('Please select a PDF file');
209
  }
210
  };
211
 
212
- const handleDragOver = (event: React.DragEvent) => {
213
  event.preventDefault();
214
  setDragOver(true);
215
  };
@@ -224,6 +231,14 @@ const PDPDialog: React.FC<PDPDialogProps> = ({ isOpen, onClose, onSubmit }) => {
224
  return;
225
  }
226
 
 
 
 
 
 
 
 
 
227
  onSubmit(formData);
228
  onClose();
229
 
@@ -236,7 +251,7 @@ const PDPDialog: React.FC<PDPDialogProps> = ({ isOpen, onClose, onSubmit }) => {
236
  });
237
  };
238
 
239
- const handleOverlayClick = (event: React.MouseEvent) => {
240
  if (event.target === event.currentTarget) {
241
  onClose();
242
  }
@@ -277,7 +292,7 @@ const PDPDialog: React.FC<PDPDialogProps> = ({ isOpen, onClose, onSubmit }) => {
277
  <TextArea
278
  placeholder="Describe your career aspirations and goals..."
279
  value={formData.careerGoal}
280
- onChange={(e) => setFormData(prev => ({ ...prev, careerGoal: e.target.value }))}
281
  />
282
  </FormGroup>
283
 
@@ -286,7 +301,7 @@ const PDPDialog: React.FC<PDPDialogProps> = ({ isOpen, onClose, onSubmit }) => {
286
  <TextArea
287
  placeholder="Any specific skills, industries, or preferences you'd like to mention..."
288
  value={formData.additionalContext}
289
- onChange={(e) => setFormData(prev => ({ ...prev, additionalContext: e.target.value }))}
290
  />
291
  </FormGroup>
292
 
@@ -295,7 +310,7 @@ const PDPDialog: React.FC<PDPDialogProps> = ({ isOpen, onClose, onSubmit }) => {
295
  <DateInput
296
  type="date"
297
  value={formData.targetDate}
298
- onChange={(e) => setFormData(prev => ({ ...prev, targetDate: e.target.value }))}
299
  min={new Date().toISOString().split('T')[0]}
300
  />
301
  </FormGroup>
 
1
+ import React, { useState, FC, ChangeEvent, DragEvent, MouseEvent } from 'react';
2
  import styled from 'styled-components';
3
 
4
+ // Declare gtag on the Window object to resolve TypeScript error
5
+ declare global {
6
+ interface Window {
7
+ gtag?: (...args: any[]) => void;
8
+ }
9
+ }
10
+
11
  const DialogOverlay = styled.div`
12
  position: fixed;
13
  top: 0;
 
183
  targetDate: string;
184
  }
185
 
186
+ const PDPDialog: FC<PDPDialogProps> = ({ isOpen, onClose, onSubmit }) => {
187
  const [formData, setFormData] = useState<PDPFormData>({
188
  cvFile: null,
189
  careerGoal: '',
 
195
 
196
  if (!isOpen) return null;
197
 
198
+ const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
199
  const file = event.target.files?.[0];
200
  if (file && file.type === 'application/pdf') {
201
+ setFormData((prev: PDPFormData) => ({ ...prev, cvFile: file }));
202
  } else {
203
  alert('Please select a PDF file');
204
  }
205
  };
206
 
207
+ const handleDrop = (event: DragEvent) => {
208
  event.preventDefault();
209
  setDragOver(false);
210
 
211
  const file = event.dataTransfer.files[0];
212
  if (file && file.type === 'application/pdf') {
213
+ setFormData((prev: PDPFormData) => ({ ...prev, cvFile: file }));
214
  } else {
215
  alert('Please select a PDF file');
216
  }
217
  };
218
 
219
+ const handleDragOver = (event: DragEvent) => {
220
  event.preventDefault();
221
  setDragOver(true);
222
  };
 
231
  return;
232
  }
233
 
234
+ // Track Generate PDP button click
235
+ if (window.gtag) {
236
+ window.gtag('event', 'click', {
237
+ 'event_category': 'Button',
238
+ 'event_label': 'Generate PDP Button - Dialog',
239
+ });
240
+ }
241
+
242
  onSubmit(formData);
243
  onClose();
244
 
 
251
  });
252
  };
253
 
254
+ const handleOverlayClick = (event: MouseEvent) => {
255
  if (event.target === event.currentTarget) {
256
  onClose();
257
  }
 
292
  <TextArea
293
  placeholder="Describe your career aspirations and goals..."
294
  value={formData.careerGoal}
295
+ onChange={(e) => setFormData((prev: PDPFormData) => ({ ...prev, careerGoal: e.target.value }))}
296
  />
297
  </FormGroup>
298
 
 
301
  <TextArea
302
  placeholder="Any specific skills, industries, or preferences you'd like to mention..."
303
  value={formData.additionalContext}
304
+ onChange={(e) => setFormData((prev: PDPFormData) => ({ ...prev, additionalContext: e.target.value }))}
305
  />
306
  </FormGroup>
307
 
 
310
  <DateInput
311
  type="date"
312
  value={formData.targetDate}
313
+ onChange={(e) => setFormData((prev: PDPFormData) => ({ ...prev, targetDate: e.target.value }))}
314
  min={new Date().toISOString().split('T')[0]}
315
  />
316
  </FormGroup>