8000 WIP - Add Free/Sales-Call/Paid badges to Modules by adamkecskes · Pull Request #7738 · codecombat/codecombat · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

WIP - Add Free/Sales-Call/Paid badges to Modules #7738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .storybook/container.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@

.sb-show-main, .sb-story {
@extend %frontend-page;
}

.tooltip {
opacity: 1 !important;
}
7 changes: 7 additions & 0 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/** @type { import('@storybook/vue').Preview } */

import fetch from 'node-fetch';
const VTooltip = require('v-tooltip')

Comment on lines +4 to +5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using ES6 import syntax for consistency with modern practices.

While the use of require is consistent with other imports in this file, consider using ES6 import syntax for better alignment with modern JavaScript practices. Also, the empty line after the import can be removed.

Here's a suggested change:

-const VTooltip = require('v-tooltip')
-
+import VTooltip from 'v-tooltip';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const VTooltip = require('v-tooltip')
import VTooltip from 'v-tooltip';


export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
Expand Down Expand Up @@ -176,6 +178,9 @@ window.Vue = Vue
window.me = {
get() {
return 'test value'
},
getSubscriptionLevel() {
return 'free'
}
}

Expand Down Expand Up @@ -227,6 +232,8 @@ const VueI18Next = {
}
}
Vue.use(VueI18Next)
Vue.use(VTooltip.default)


const { $themePath } = require('app/core/initialize-themes')
Vue.prototype.$themePath = $themePath
Expand Down
47 changes: 47 additions & 0 deletions app/components/common/elements/AccessLevelIndicator.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import AccessLevelIndicator from './AccessLevelIndicator.vue'

export default {
title: 'AccessLevelIndicator',
component: AccessLevelIndicator,
argTypes: {
level: {
control: { type: 'select', options: ['free', 'sales-call', 'paid'] },
description: 'The access level of the user',
},
displayText: {
control: 'boolean',
description: 'Whether to display the text or not',
},
displayIcon: {
control: 'boolean',
description: 'Whether to display the icon or not',
},
},
}

const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { AccessLevelIndicator },
template: '<access-level-indicator v-bind="$props" />',
})

export const Free = Template.bind({})
Free.args = {
level: 'free',
displayText: true,
displayIcon: false,
}

export const SalesCall = Template.bind({})
SalesCall.args = {
level: 'sales-call',
displayText: false,
displayIcon: true,
}

export const Paid = Template.bind({})
Paid.args = {
level: 'paid',
displayText: true,
displayIcon: true,
}
95 changes: 95 additions & 0 deletions app/components/common/elements/AccessLevelIndicator.vue
8000
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<template>
<span
v-if="isDisplayable"
v-tooltip.bottom="{
content: $t(`paywall.badge_tooltip_${level}`),
}"
:class="badgeClass"
>
<span v-if="displayIcon">{{ icon }}</span>
<span v-if="displayText">{{ $t(`paywall.badge_${level}`) }}</span>
</span>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'
import CourseSchema from 'app/schemas/models/course.schema'
const ACCESS_LEVELS = CourseSchema.properties.modules.additionalProperties.properties.access.enum

export default {
name: 'AccessLevelIndicator',
props: {
level: {
type: String,
required: false,
validator: value => ACCESS_LEVELS.includes(value),
default: 'free',
},
displayText: {
type: Boolean,
default: true,
},
displayIcon: {
type: Boolean,
default: true,
},
},
computed: {
...mapGetters({
isPaidTeacher: 'me/isPaidTeacher',
}),
isDisplayable () {
const userDisplayMap = {
free: ['free', 'sales-call'], // non-paying users will see the 'free' and 'sales-call' badges
'sales-call': ['paid'], // users after sales call will see the 'paid' badges
paid: [], // I'm not sure if we'll have this for users, but if we'll have no badges needed.
}
const userLevel = this.isPaidTeacher ? 'paid' : 'free'
return userDisplayMap[userLevel].includes(this.level)
},
badgeClass () {
return {
badge: true,
[`badge-${this.level}`]: true,
}
},
icon () {
const icons = 5D32 {
free: '✨',
'sales-call': '📞',
paid: '🔒',
}
return icons[this.level] || ''
Comment on lines +58 to +62
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use consistent icons instead of emojis

Using emojis for icons may lead to inconsistent rendering across different platforms and devices. It's better to use consistent icon components or SVGs that align with the application's design system.

Consider importing and using icon components from your UI library. For example:

+import FreeIcon from 'components/icons/FreeIcon.vue'
+import SalesCallIcon from 'components/icons/SalesCallIcon.vue'
+import PaidIcon from 'components/icons/PaidIcon.vue'

 // In computed property
 icon () {
-  const icons = {
-    free: '✨',
-    'sales-call': '📞',
-    paid: '🔒',
+  const icons = {
+    free: FreeIcon,
+    'sales-call': SalesCallIcon,
+    paid: PaidIcon,
   }
   return icons[this.level] || ''
 },

And update the template to use the icon components:

 <span v-if="displayIcon">
-  {{ icon }}
+  <component :is="icon" />
 </span>

Committable suggestion was skipped due to low confidence.

},
Comment on lines +56 to +63
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using consistent icons instead of emojis

Using emojis for icons may lead to inconsistent rendering across different platforms and devices. It's better to use consistent icon components or SVGs that align with the application's design system.

Consider importing and using icon components from your UI library. For example:

import FreeIcon from 'components/icons/FreeIcon.vue'
import SalesCallIcon from 'components/icons/SalesCallIcon.vue'
import PaidIcon from 'components/icons/PaidIcon.vue'

// In computed property
icon() {
  const icons = {
    free: FreeIcon,
    'sales-call': SalesCallIcon,
    paid: PaidIcon,
  }
  return icons[this.level] || null
},

Then update the template to use the icon components:

<component :is="icon" v-if="displayIcon && icon" />

This approach ensures consistent rendering across all platforms and devices.

},
async created () {
await this.ensurePrepaidsLoadedForTeacher(me.get('_id'))
},
methods: {
...mapActions({
ensurePrepaidsLoadedForTeacher: 'prepaids/ensurePrepaidsLoadedForTeacher',
}),
},
}
</script>

<style scoped lang="scss">
.badge {
padding: 5px;
border-radius: 3px;
color: white;
font-size: 12px;
}

.badge-free {
background-color: green;
}

.badge-sales-call {
background-color: orange;
}

.badge-paid {
background-color: red;
}
</style>
13 changes: 13 additions & 0 deletions app/components/common/labels/CodeRenderer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script>
export default {
props: {
content: {
type: String,
required: true,
},
},
render (h) {
return h('span', { domProps: { innerHTML: this.content.replace(/`(.*?)`/g, '<code>$1</code>') } })
},
}
</script>
Loading
Loading
0