diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml
index 5338837c..f4b87366 100644
--- a/.github/workflows/ui-tests.yml
+++ b/.github/workflows/ui-tests.yml
@@ -100,6 +100,7 @@ jobs:
bench --site lms.test execute frappe.utils.install.complete_setup_wizard
bench --site lms.test execute frappe.tests.ui_test_helpers.create_test_user
bench --site lms.test set-password frappe@example.com admin
+ bench --site lms.test execute lms.lms.utils.persona_captured
- name: cypress pre-requisites
run: |
diff --git a/cypress.config.js b/cypress.config.js
index 5e1c68ea..c7c1354e 100644
--- a/cypress.config.js
+++ b/cypress.config.js
@@ -13,6 +13,6 @@ module.exports = defineConfig({
openMode: 0,
},
e2e: {
- baseUrl: "http://testui:8000",
+ baseUrl: "http://pertest:8000",
},
});
diff --git a/cypress/e2e/course_creation.cy.js b/cypress/e2e/course_creation.cy.js
index 69c0f1ca..28b97041 100644
--- a/cypress/e2e/course_creation.cy.js
+++ b/cypress/e2e/course_creation.cy.js
@@ -19,13 +19,6 @@ describe("Course Creation", () => {
);
cy.fixture("profile.png", "base64").then((fileContent) => {
- /* cy.get('input[type="file"]').should("be.hidden").attachFile({
- fileContent,
- fileName: "profile.png",
- mimeType: "image/png",
- encoding: "base64",
- }); */
-
cy.get("div")
.contains("Course Image")
.siblings("div")
diff --git a/frappe-ui b/frappe-ui
index 29307e4f..8cd9b06a 160000
--- a/frappe-ui
+++ b/frappe-ui
@@ -1 +1 @@
-Subproject commit 29307e4fffaacdbb3d9c5d95c5270b2f245a5607
+Subproject commit 8cd9b06a5ed50dc181d9672b2fe84c1594b52b48
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index d890f55a..c79397af 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -24,7 +24,7 @@ const router = useRouter()
const noSidebar = ref(false)
router.beforeEach((to, from, next) => {
- if (to.query.fromLesson) {
+ if (to.query.fromLesson || to.path === '/persona') {
noSidebar.value = true
} else {
noSidebar.value = false
diff --git a/frontend/src/components/AppSidebar.vue b/frontend/src/components/AppSidebar.vue
index 50c4f318..0dcc59f0 100644
--- a/frontend/src/components/AppSidebar.vue
+++ b/frontend/src/components/AppSidebar.vue
@@ -76,7 +76,7 @@
/>
{
icon: 'LogIn',
fields: [
{
- label: 'Identify User Persona',
+ label: 'Identify User Category',
name: 'user_category',
type: 'checkbox',
description:
- 'Enable this option to identify the user persona during signup.',
+ 'Enable this option to identify the user category during signup.',
},
{
label: 'Disable signup',
diff --git a/frontend/src/pages/Courses.vue b/frontend/src/pages/Courses.vue
index bf8d4ec2..58b4717a 100644
--- a/frontend/src/pages/Courses.vue
+++ b/frontend/src/pages/Courses.vue
@@ -96,6 +96,7 @@
import {
Breadcrumbs,
Button,
+ call,
createListResource,
FormControl,
Select,
@@ -107,6 +108,7 @@ import { BookOpen, Plus } from 'lucide-vue-next'
import { sessionStore } from '@/stores/session'
import { canCreateCourse } from '@/utils'
import CourseCard from '@/components/CourseCard.vue'
+import router from '../router'
const user = inject('$user')
const dayjs = inject('$dayjs')
@@ -121,6 +123,7 @@ const currentTab = ref('Live')
const { brand } = sessionStore()
onMounted(() => {
+ identifyUserPersona()
setFiltersFromQuery()
updateCourses()
categories.value = [
@@ -145,16 +148,52 @@ const courses = createListResource({
pageLength: pageLength.value,
start: start.value,
onSuccess(data) {
- let allCategories = data.map((course) => course.category)
- allCategories = allCategories.filter(
- (category, index) => allCategories.indexOf(category) === index && category
- )
- if (categories.value.length <= allCategories.length) {
- updateCategories(data)
- }
+ setCategories(data)
},
})
+const setCategories = (data) => {
+ let allCategories = data.map((course) => course.category)
+ allCategories = allCategories.filter(
+ (category, index) => allCategories.indexOf(category) === index && category
+ )
+ if (categories.value.length <= allCategories.length) {
+ updateCategories(data)
+ }
+}
+
+const isPersonaCaptured = async () => {
+ let persona = await call('frappe.client.get_single_value', {
+ doctype: 'LMS Settings',
+ field: 'persona_captured',
+ })
+ return persona
+}
+
+const identifyUserPersona = async () => {
+ let personaCaptured = await isPersonaCaptured()
+ debugger
+ console.log('personaCaptured', personaCaptured)
+ console.log('user.data?.is_system_manager', user.data?.is_system_manager)
+ console.log('user.data?.developer_mode', user.data?.developer_mode)
+
+ if (
+ user.data?.is_system_manager &&
+ !user.data?.developer_mode &&
+ !personaCaptured
+ ) {
+ call('frappe.client.get_count', {
+ doctype: 'LMS Course',
+ }).then((data) => {
+ if (!data) {
+ router.push({
+ name: 'PersonaForm',
+ })
+ }
+ })
+ }
+}
+
const updateCourses = () => {
updateFilters()
courses.update({
diff --git a/frontend/src/pages/PersonaForm.vue b/frontend/src/pages/PersonaForm.vue
new file mode 100644
index 00000000..0ba7cf4d
--- /dev/null
+++ b/frontend/src/pages/PersonaForm.vue
@@ -0,0 +1,199 @@
+
+
+
+
+
+
+ Learning
+
+
+
+
+
+ {{ __('1. What best describes your role?') }}
+
+
+
+
+
+
+
+ {{ __('2. How many students are you planning to teach?') }}
+
+
+
+
+
+
+
+
+ {{ __('3. What is your main use case for Frappe Learning?') }}
+
+
+
+
+
+
+
+
+ {{ __('4. Are you currently using any Frappe products?') }}
+
+
+
+
+
+
+
+
+
+
+ {{ __('Skip') }}
+
+
+
+
+
diff --git a/frontend/src/router.js b/frontend/src/router.js
index 7eba6f7a..fb04cc7d 100644
--- a/frontend/src/router.js
+++ b/frontend/src/router.js
@@ -210,6 +210,11 @@ const routes = [
name: 'AssignmentSubmissionList',
component: () => import('@/pages/AssignmentSubmissionList.vue'),
},
+ {
+ path: '/persona',
+ name: 'PersonaForm',
+ component: () => import('@/pages/PersonaForm.vue'),
+ },
]
let router = createRouter({
diff --git a/frontend/vite.config.js b/frontend/vite.config.js
index 4be6085e..16881bc4 100644
--- a/frontend/vite.config.js
+++ b/frontend/vite.config.js
@@ -25,7 +25,7 @@ export default defineConfig({
}),
],
server: {
- allowedHosts: ['fs', 'bs'],
+ allowedHosts: ['fs', 'persona'],
},
resolve: {
alias: {
diff --git a/lms/lms/api.py b/lms/lms/api.py
index cc8f7df0..1a133532 100644
--- a/lms/lms/api.py
+++ b/lms/lms/api.py
@@ -184,9 +184,10 @@ def get_user_info():
)
user.is_fc_site = is_fc_site()
user.is_system_manager = "System Manager" in user.roles
+ user.sitename = frappe.local.site
+ user.developer_mode = frappe.conf.developer_mode
if user.is_fc_site and user.is_system_manager:
user.site_info = current_site_info()
- user.sitename = frappe.local.site
return user
@@ -678,13 +679,13 @@ def get_categories(doctype, filters):
@frappe.whitelist()
def get_members(start=0, search=""):
"""Get members for the given search term and start index.
- Args: start (int): Start index for the query.
+ Args: start (int): Start index for the query.
<<<<<<< HEAD
- search (str): Search term to filter the results.
+ search (str): Search term to filter the results.
=======
- search (str): Search term to filter the results.
+ search (str): Search term to filter the results.
>>>>>>> 4869bba7bbb2fb38477d6fc29fb3b5838e075577
- Returns: List of members.
+ Returns: List of members.
"""
filters = {"enabled": 1, "name": ["not in", ["Administrator", "Guest"]]}
@@ -1389,3 +1390,17 @@ def add_an_evaluator(email):
evaluator.insert()
return evaluator
+
+
+@frappe.whitelist()
+def capture_user_persona(responses):
+ frappe.only_for("System Manager")
+ data = frappe.parse_json(responses)
+ data = json.dumps(data)
+ response = frappe.integrations.utils.make_post_request(
+ "https://school.frappe.io/api/method/capture-persona",
+ data={"response": data},
+ )
+ if response.get("message").get("name"):
+ frappe.db.set_single_value("LMS Settings", "persona_captured", True)
+ return response
diff --git a/lms/lms/doctype/lms_settings/lms_settings.json b/lms/lms/doctype/lms_settings/lms_settings.json
index 772a6fbe..8bf72de4 100644
--- a/lms/lms/doctype/lms_settings/lms_settings.json
+++ b/lms/lms/doctype/lms_settings/lms_settings.json
@@ -8,6 +8,7 @@
"general_tab",
"default_home",
"send_calendar_invite_for_evaluations",
+ "persona_captured",
"column_break_zdel",
"allow_guest_access",
"enable_learning_paths",
@@ -108,7 +109,7 @@
"default": "0",
"fieldname": "user_category",
"fieldtype": "Check",
- "label": "Identify User Persona"
+ "label": "Identify User Category"
},
{
"default": "0",
@@ -380,6 +381,10 @@
"fieldtype": "Attach Image",
"label": "Meta Image"
},
+ {
+ "fieldname": "column_break_xijv",
+ "fieldtype": "Column Break"
+ },
{
"description": "Common keywords that will be used for all pages",
"fieldname": "meta_keywords",
@@ -387,15 +392,18 @@
"label": "Meta Keywords"
},
{
- "fieldname": "column_break_xijv",
- "fieldtype": "Column Break"
+ "default": "0",
+ "fieldname": "persona_captured",
+ "fieldtype": "Check",
+ "label": "Persona Captured",
+ "read_only": 1
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
- "modified": "2025-04-19 12:19:24.037931",
+ "modified": "2025-04-22 16:05:27.914422",
"modified_by": "sayali@frappe.io",
"module": "LMS",
"name": "LMS Settings",
diff --git a/lms/lms/utils.py b/lms/lms/utils.py
index 9a39b4a9..83e219ec 100644
--- a/lms/lms/utils.py
+++ b/lms/lms/utils.py
@@ -2167,3 +2167,7 @@ def get_palette(full_name):
hash_name = hashlib.md5(encoded_name).hexdigest()
idx = cint((int(hash_name[4:6], 16) + 1) / 5.33)
return palette[idx % 8]
+
+
+def persona_captured():
+ frappe.db.set_single_value("LMS Settings", "persona_captured", 1)