Skip to content

Commit 4b8fa3e

Browse files
committed
feat: add new features to Pro plan including quiz exam generator, study guide, and embeddable widget
1 parent 5df180d commit 4b8fa3e

6 files changed

Lines changed: 94 additions & 26 deletions

File tree

src/components/landing/ProPreview.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ const TABLE_ROWS = [
2929
{ key: 'fullscreen', free: true, pro: true },
3030
{ key: 'insight', free: true, pro: true },
3131
{ key: 'pseudocode', free: true, pro: true },
32-
{ key: 'notes', free: true, pro: true },
32+
{ key: 'notes', free: 'notesFree', pro: 'notesPro' },
3333
{ key: 'videoExport', free: 'videoExportFree', pro: 'videoExportPro' },
3434
{ key: 'customInput', free: false, pro: true },
3535
{ key: 'comparison', free: false, pro: true },
3636
{ key: 'presentation', free: false, pro: true },
37+
{ key: 'quizExam', free: false, pro: true },
38+
{ key: 'embedWidget', free: false, pro: true },
3739
];
3840

3941
function ProPreview() {

src/components/landing/ProPreview.test.jsx

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,14 @@ describe('ProPreview', () => {
132132
expect(
133133
screen.getByText('Presentation Mode (Dedicated For Teachers)')
134134
).toBeInTheDocument();
135-
expect(screen.getByText('Step-by-step Pseudocode')).toBeInTheDocument();
136135
expect(
137-
screen.getByText('Save Your Notes on Every Algorithm')
136+
screen.getByText('Custom Quiz & Exam Generator')
137+
).toBeInTheDocument();
138+
expect(
139+
screen.getByText('Embeddable Visualizer Widget')
138140
).toBeInTheDocument();
141+
expect(screen.getByText('Step-by-step Pseudocode')).toBeInTheDocument();
142+
expect(screen.getByText('Study Notes')).toBeInTheDocument();
139143
});
140144

141145
it('should render check icon for features on both plans', () => {
@@ -150,7 +154,7 @@ describe('ProPreview', () => {
150154
it('should render x icon for features missing on the free plan', () => {
151155
const { container } = renderComponent();
152156
const crosses = excludedIcons(container);
153-
expect(crosses.length).toBe(3);
157+
expect(crosses.length).toBe(5);
154158
crosses.forEach(cross => {
155159
expect(cross).toHaveClass('text-red-500');
156160
});
@@ -171,20 +175,18 @@ describe('ProPreview', () => {
171175
).toBe('Included');
172176
});
173177

174-
it('should mark pseudocode and notes as included on both plans', () => {
178+
it('should mark pseudocode as included on both plans', () => {
175179
const { container } = renderComponent();
176180
const rows = [...container.querySelectorAll('tbody tr')];
177-
['Step-by-step Pseudocode', 'Save Your Notes on Every Algorithm'].forEach(
178-
label => {
179-
const row = rows.find(tr => tr.textContent.includes(label));
180-
const cells = row.querySelectorAll('td');
181-
expect(cells[1].querySelector('svg').getAttribute('aria-label')).toBe(
182-
'Included'
183-
);
184-
expect(cells[2].querySelector('svg').getAttribute('aria-label')).toBe(
185-
'Included'
186-
);
187-
}
181+
const pseudocodeRow = rows.find(tr =>
182+
tr.textContent.includes('Step-by-step Pseudocode')
183+
);
184+
const cells = pseudocodeRow.querySelectorAll('td');
185+
expect(cells[1].querySelector('svg').getAttribute('aria-label')).toBe(
186+
'Included'
187+
);
188+
expect(cells[2].querySelector('svg').getAttribute('aria-label')).toBe(
189+
'Included'
188190
);
189191
});
190192

@@ -196,6 +198,16 @@ describe('ProPreview', () => {
196198
expect(screen.getByText('Watermark-Free Exports')).toBeInTheDocument();
197199
});
198200

201+
it('should render study notes cells as text instead of icons', () => {
202+
renderComponent();
203+
expect(
204+
screen.getByText('Basic Text Notes per Algorithm')
205+
).toBeInTheDocument();
206+
expect(
207+
screen.getByText('Study Guide Export, Code Snippets & Search')
208+
).toBeInTheDocument();
209+
});
210+
199211
it('should not render any price', () => {
200212
renderComponent();
201213
expect(screen.queryByText('Free forever')).not.toBeInTheDocument();
@@ -222,7 +234,7 @@ describe('ProPreview', () => {
222234
const proColumnCells = [...container.querySelectorAll('tbody tr')].map(
223235
tr => tr.querySelectorAll('td')[2]
224236
);
225-
expect(proColumnCells.length).toBe(12);
237+
expect(proColumnCells.length).toBe(14);
226238
});
227239
});
228240

src/i18n/locales/ar/translation.json

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
},
7878
"eyebrow": "الخطة الاحترافية",
7979
"headline": "تقدّم أكثر مع الخطة الاحترافية",
80-
"subheadline": "النسخة المدفوعة القادمة ستفتح ميزات أقوى مثل المدخلات المخصصة والمقارنات جنبًا إلى جنب والتصدير بدون علامة مائية والمزيد.",
80+
"subheadline": "النسخة المدفوعة القادمة ستفتح ميزات أقوى مثل المدخلات المخصصة والمقارنات جنبًا إلى جنب والتصدير بدون علامة مائية والاختبارات المخصصة والأدوات القابلة للتضمين.",
8181
"featuresHeading": "ما تفتحه الخطة الاحترافية",
8282
"features": {
8383
"customInput": {
@@ -95,6 +95,18 @@
9595
"presentation": {
9696
"title": "وضع العرض",
9797
"body": "استخدم عرضًا تعليميًا أكثر تركيزًا مع واجهة أبسط وحالات مرئية أكبر."
98+
},
99+
"quizExam": {
100+
"title": "مولّد الاختبارات والامتحانات",
101+
"body": "حوّل أي مجموعة خوارزميات إلى اختبار قابل للتصحيح أو امتحان محدّد بوقت، قابل للتصدير كملف PDF."
102+
},
103+
"studyGuide": {
104+
"title": "ملاحظات دراسية متطورة",
105+
"body": "صدّر ملاحظاتك كدليل دراسة، وأرفق مقتطفات أكواد قابلة للتشغيل، وابحث في كل خوارزمية درستها."
106+
},
107+
"embedWidget": {
108+
"title": "أداة قابلة للتضمين",
109+
"body": "ضع عارضًا تفاعليًا مباشرًا في موقع كورسك أو شرائحك أو مدونتك."
98110
}
99111
},
100112
"form": {
@@ -1452,7 +1464,7 @@
14521464
"badge": "قريباً",
14531465
"badgeJoined": "أنت على القائمة",
14541466
"heading": "انطلق أبعد مع الخطة الاحترافية",
1455-
"subheading": "مصممة للتحضير للمقابلات والتدريس في الصف: مدخلات مخصصة، مقارنات جنباً إلى جنب، تصدير بدون علامة مائية، والمزيد قريباً.",
1467+
"subheading": "مصممة للتحضير للمقابلات والتدريس في الصف: مدخلات مخصصة، مقارنات جنباً إلى جنب، تصدير بدون علامة مائية، اختبارات مخصصة، عارضات قابلة للتضمين، والمزيد قريباً.",
14561468
"cta": "انضم إلى قائمة الانتظار",
14571469
"ctaJoined": "الخطة الاحترافية",
14581470
"table": {
@@ -1473,8 +1485,12 @@
14731485
"customInput": "مدخلات مخصصة",
14741486
"comparison": "وضع مقارنة الخوارزميات",
14751487
"presentation": "وضع العرض (مخصص للمعلمين)",
1488+
"quizExam": "مولّد الاختبارات والامتحانات",
1489+
"embedWidget": "أداة عارض قابلة للتضمين",
14761490
"pseudocode": "شبه الشيفرة خطوة بخطوة",
1477-
"notes": "ملاحظات على كل خوارزمية"
1491+
"notes": "ملاحظات دراسية",
1492+
"notesFree": "ملاحظات نصية أساسية على كل خوارزمية",
1493+
"notesPro": "تصدير دليل دراسة، مقتطفات أكواد، وبحث"
14781494
}
14791495
},
14801496
"faq": {

src/i18n/locales/en/translation.json

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
},
7878
"eyebrow": "The Pro Plan",
7979
"headline": "Go further with the Pro Plan",
80-
"subheadline": "The upcoming paid plan will unlock more powerful features like custom inputs, side-by-side comparisons, watermark-free exports, and more.",
80+
"subheadline": "The upcoming paid plan will unlock more powerful features like custom inputs, side-by-side comparisons, watermark-free exports, custom quizzes, and embeddable widgets.",
8181
"featuresHeading": "What the Pro Plan unlocks",
8282
"features": {
8383
"customInput": {
@@ -95,6 +95,18 @@
9595
"presentation": {
9696
"title": "Presentation mode",
9797
"body": "Use a focused teaching view with cleaner chrome and larger visual states."
98+
},
99+
"quizExam": {
100+
"title": "Custom quiz & exam generator",
101+
"body": "Turn any algorithm set into a gradeable quiz or timed exam, exportable as PDF."
102+
},
103+
"studyGuide": {
104+
"title": "Supercharged study notes",
105+
"body": "Export your notes as a study guide, attach runnable code snippets, and search across every algorithm you've studied."
106+
},
107+
"embedWidget": {
108+
"title": "Embeddable widget",
109+
"body": "Drop a live, interactive visualizer into your own course site, slides, or blog."
98110
}
99111
},
100112
"form": {
@@ -1452,7 +1464,7 @@
14521464
"badge": "Coming Soon",
14531465
"badgeJoined": "You're on the list",
14541466
"heading": "Go Further with Pro",
1455-
"subheading": "Built for interview prep and classroom teaching: custom inputs, side-by-side comparisons, watermark-free exports, and more...",
1467+
"subheading": "Built for interview prep and classroom teaching: custom inputs, side-by-side comparisons, watermark-free exports, custom quizzes, embeddable visualizers, and more...",
14561468
"cta": "Join The Waitlist",
14571469
"ctaJoined": "View Your Spot",
14581470
"table": {
@@ -1473,8 +1485,12 @@
14731485
"customInput": "Custom Inputs",
14741486
"comparison": "Algorithms Comparison Mode",
14751487
"presentation": "Presentation Mode (Dedicated For Teachers)",
1488+
"quizExam": "Custom Quiz & Exam Generator",
1489+
"embedWidget": "Embeddable Visualizer Widget",
14761490
"pseudocode": "Step-by-step Pseudocode",
1477-
"notes": "Save Your Notes on Every Algorithm"
1491+
"notes": "Study Notes",
1492+
"notesFree": "Basic Text Notes per Algorithm",
1493+
"notesPro": "Study Guide Export, Code Snippets & Search"
14781494
}
14791495
},
14801496
"faq": {

src/i18n/locales/fr/translation.json

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
},
7878
"eyebrow": "Le Plan Pro",
7979
"headline": "Allez plus loin avec le Plan Pro",
80-
"subheadline": "La version payante à venir débloquera des fonctionnalités plus puissantes comme des entrées personnalisées, des comparaisons côte à côte, des exports sans filigrane et plus encore.",
80+
"subheadline": "La version payante à venir débloquera des fonctionnalités plus puissantes comme des entrées personnalisées, des comparaisons côte à côte, des exports sans filigrane, des quiz personnalisés et des widgets intégrables.",
8181
"featuresHeading": "Ce que le Plan Pro débloque",
8282
"features": {
8383
"customInput": {
@@ -95,6 +95,18 @@
9595
"presentation": {
9696
"title": "Mode présentation",
9797
"body": "Utilisez une vue d'enseignement plus ciblée avec moins de chrome et des états visuels plus grands."
98+
},
99+
"quizExam": {
100+
"title": "Générateur de quiz et d'examens",
101+
"body": "Transformez n'importe quel ensemble d'algorithmes en quiz noté ou examen chronométré, exportable en PDF."
102+
},
103+
"studyGuide": {
104+
"title": "Notes d'étude améliorées",
105+
"body": "Exportez vos notes en guide de révision, joignez des extraits de code exécutables et recherchez dans chaque algorithme que vous avez étudié."
106+
},
107+
"embedWidget": {
108+
"title": "Widget intégrable",
109+
"body": "Intégrez un visualiseur interactif en direct dans votre site de cours, vos diapositives ou votre blog."
98110
}
99111
},
100112
"form": {
@@ -1452,7 +1464,7 @@
14521464
"badge": "Bientôt Disponible",
14531465
"badgeJoined": "Vous êtes sur la liste",
14541466
"heading": "Allez Plus Loin avec Pro",
1455-
"subheading": "Conçu pour la préparation aux entretiens et l'enseignement en classe : entrées personnalisées, comparaisons côte à côte, exports sans filigrane, et plus encore, bientôt disponible.",
1467+
"subheading": "Conçu pour la préparation aux entretiens et l'enseignement en classe : entrées personnalisées, comparaisons côte à côte, exports sans filigrane, quiz personnalisés, visualiseurs intégrables, et plus encore, bientôt disponible.",
14561468
"cta": "Rejoignez la liste d'attente",
14571469
"ctaJoined": "Plan Pro",
14581470
"table": {
@@ -1473,8 +1485,12 @@
14731485
"customInput": "Entrées personnalisées",
14741486
"comparison": "Mode comparaison d'algorithmes",
14751487
"presentation": "Mode présentation (dédié aux enseignants)",
1488+
"quizExam": "Générateur de quiz et d'examens",
1489+
"embedWidget": "Widget visualiseur intégrable",
14761490
"pseudocode": "Pseudo-code pas à pas",
1477-
"notes": "Notes sur chaque algorithme"
1491+
"notes": "Notes d'étude",
1492+
"notesFree": "Notes texte de base sur chaque algorithme",
1493+
"notesPro": "Export en guide de révision, extraits de code et recherche"
14781494
}
14791495
},
14801496
"faq": {

src/pages/ProComingSoonPage.jsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
import { useEffect, useRef, useState } from 'react';
88
import { useSearchParams } from 'react-router-dom';
99
import {
10+
CodeBlock,
1011
Columns,
12+
Exam,
1113
Export,
14+
Notebook,
1215
PlusCircle,
1316
Presentation,
1417
Sliders,
@@ -34,6 +37,9 @@ const FEATURE_ITEMS = [
3437
{ key: 'comparison', Icon: Columns },
3538
{ key: 'export', Icon: Export },
3639
{ key: 'presentation', Icon: Presentation },
40+
{ key: 'quizExam', Icon: Exam },
41+
{ key: 'studyGuide', Icon: Notebook },
42+
{ key: 'embedWidget', Icon: CodeBlock },
3743
];
3844

3945
const PRO_SORT_BAR_HEIGHTS = [40, 65, 30, 80, 50, 70];

0 commit comments

Comments
 (0)