Remove features de-planned for beta
This commit is contained in:
@@ -1,28 +0,0 @@
|
||||
<template>
|
||||
<div class="w-full h-full">
|
||||
<div v-if="brandingStore.value.loading">
|
||||
<v-progress-linear indeterminate></v-progress-linear>
|
||||
</div>
|
||||
<div v-else>
|
||||
<content-list :creator-id="brandingStore.value.id"
|
||||
></content-list>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script async setup>
|
||||
import {useBrandingStore} from "@/stores/brandingStore.js";
|
||||
import ContentList from "@/views/contents/ContentList.vue";
|
||||
import {useRouter} from "vue-router";
|
||||
const brandingStore = useBrandingStore()
|
||||
const router = useRouter();
|
||||
|
||||
const createHtmlContent = () => {
|
||||
router.push('/content/editor');
|
||||
}
|
||||
|
||||
const createContent = () => {
|
||||
router.push('/content/post');
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -1,89 +0,0 @@
|
||||
<script setup>
|
||||
import { useBrandingStore } from "@/stores/brandingStore.js";
|
||||
import { ref } from "vue";
|
||||
|
||||
const branding = useBrandingStore();
|
||||
const menu = ref(false); // C'est pour le menu déroulant!
|
||||
|
||||
// Fonction pour convertir une couleur hexadécimale en RGB afin d'appliquer la transparence avec nos couleurs du backend hex a rgb
|
||||
function hexToRgb(hex) {
|
||||
const bigint = parseInt(hex.replace('#', ''), 16);
|
||||
const r = (bigint >> 16) & 255;
|
||||
const g = (bigint >> 8) & 255;
|
||||
const b = bigint & 255;
|
||||
return `${r}, ${g}, ${b}`;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center justify-center">
|
||||
<!-- ExclusiveCard -->
|
||||
<div
|
||||
class="rounded-lg w-[290px] h-[380px] relative bg-hSurface"
|
||||
:style="{
|
||||
boxShadow: '0 10px 10px rgba(0, 0, 0, 0.3)',
|
||||
borderColor: `rgba(${hexToRgb('--h-secondary')}, 0.4)`,
|
||||
borderWidth: '1px',
|
||||
}"
|
||||
>
|
||||
<!-- Conteneur pour aligner le titre et le bouton -->
|
||||
<div
|
||||
class="flex items-center justify-between py-2 px-3 text-hOnPrimary"
|
||||
>
|
||||
<div class="text-md">Comment créer un logo</div>
|
||||
|
||||
<!-- Bouton à trois points avec menu déroulant -->
|
||||
<v-menu v-model="menu" activator="parent" offset-y>
|
||||
<template #activator="{ props }">
|
||||
<button
|
||||
v-bind="props"
|
||||
class="text-gray-600 text-hOnPrimary"
|
||||
>
|
||||
<i class="mdi mdi-dots-vertical text-lg"></i>
|
||||
</button>
|
||||
</template>
|
||||
<v-list class="bg-hSecondary text-hOnSecondary">
|
||||
<v-list-item title="Modifier" @click="modifier" />
|
||||
<v-list-item title="Effacer" @click="effacer" />
|
||||
<v-list-item title="Reporter" @click="reporter" />
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</div>
|
||||
|
||||
<div class="relative h-[170px] overflow-hidden">
|
||||
<img
|
||||
src="/images/hutopymedia/banners/hutopyul.png"
|
||||
class="w-full h-full object-cover blur-md"
|
||||
alt="image"
|
||||
/>
|
||||
<div class="absolute inset-0 flex items-center justify-center">
|
||||
<i class="mdi mdi-lock text-7xl p-2 rounded-full text-hSecondary border-2 border-solid border-hSecondary"
|
||||
></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-end pa-2 px-4 text-hOnPrimary">
|
||||
14-05-2024
|
||||
</div>
|
||||
|
||||
<div class="text-justify px-4 text-md text-hOnPrimary">
|
||||
Tutoriel sur comment s'assurer d'avoir un logo unique et percutant
|
||||
qui se démarque de la concurrence.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
<script>
|
||||
function modifier() {
|
||||
console.log("Modifier l'élément");
|
||||
}
|
||||
function effacer() {
|
||||
console.log("Effacer l'élément");
|
||||
}
|
||||
function reporter() {
|
||||
console.log("Reporter l'élément");
|
||||
}
|
||||
</script>
|
||||
@@ -1,169 +0,0 @@
|
||||
<template>
|
||||
<div class="overflow-hidden relative" @wheel="handleScroll">
|
||||
<!-- Container that holds all the posts and permet le défilement -->
|
||||
<div class="relative h-[1000px] max-h-[1000px] overflow-hidden p-4">
|
||||
<div class="transition-transform duration-500" :style="{ transform: `translateY(-${scrollPosition}px)` }">
|
||||
<!-- Grille avec colonnes dynamiques basées sur la largeur -->
|
||||
<div class="grid gap-3 grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 min-w-[250px]">
|
||||
<div v-for="(item, index) in contenuexclusif" :key="index"
|
||||
class="my-1 text-white rounded-lg w-full border-2 shadow h-[380px] hover-card relative overflow-hidden bg-hPrimary text-hOnPrimary border-hSecondary">
|
||||
<div class="flex justify-center items-center">
|
||||
</div>
|
||||
<div>
|
||||
<img :src="item.photo" alt="photo" class="w-full h-auto max-h-[170px] object-cover" />
|
||||
|
||||
<!-- Section du nombre de clics et du bouton d'édition -->
|
||||
<div class="flex flex-row justify-between items-center p-2">
|
||||
<div class="flex items-center">
|
||||
<p class="text-xs">{{ item.date }}</p>
|
||||
<p class="text-xs px-2">|</p>
|
||||
<p class="text-xs">200 clicks</p>
|
||||
</div>
|
||||
<!-- Bouton pour éditer le contenu à droite -->
|
||||
<v-btn class="" variant="plain" @click="editCard(item)">
|
||||
<v-icon>mdi-dots-vertical</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<p class="text-md p-4">{{ item.title }}</p>
|
||||
<!-- Section des étoiles, fixée dans le coin inférieur droit -->
|
||||
<div v-if="item.rating" class="stars flex justify-end p-2 absolute bottom-0 right-0">
|
||||
<!-- Génération dynamique des étoiles -->
|
||||
<span v-for="star in 5" :key="star" class="text-yellow-500">
|
||||
<v-icon v-if="star <= item.rating">mdi-star</v-icon>
|
||||
<v-icon v-else>mdi-star-outline</v-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, defineProps } from 'vue';
|
||||
|
||||
function hexToRgb(hex) {
|
||||
let shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
||||
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
|
||||
return r + r + g + g + b + b;
|
||||
});
|
||||
|
||||
let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
}
|
||||
|
||||
function getRGB(hexColor) {
|
||||
const rgb = hexToRgb(hexColor);
|
||||
return `${rgb.r}, ${rgb.g}, ${rgb.b}`;
|
||||
}
|
||||
|
||||
const contenuexclusif = ref([
|
||||
{ title: 'Créer un site web moderne', description: 'Un guide pour concevoir un site qui attire l\'attention et se démarque.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 2, date: '2024-09-19' },
|
||||
{ title: ' Les secrets d’un logo réussiLes secrets d’un logo réussiLes secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
{ title: 'Les secrets d’un logo réussi', description: 'Découvrez les astuces pour un logo mémorable et distinctif.', photo: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png', rating: 4, date: '2024-09-19' },
|
||||
// autres objets...
|
||||
]);
|
||||
|
||||
const scrollPosition = ref(0);
|
||||
const cardHeight = 320;
|
||||
|
||||
const props = defineProps({
|
||||
creator: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
function handleScroll(event) {
|
||||
event.preventDefault();
|
||||
const scrollSpeed = 100;
|
||||
scrollPosition.value += event.deltaY > 0 ? scrollSpeed : -scrollSpeed;
|
||||
|
||||
const totalRows = Math.ceil(contenuexclusif.value.length / getCurrentCols());
|
||||
const visibleRows = 1000 / cardHeight;
|
||||
const maxScrollPosition = totalRows * cardHeight - visibleRows * cardHeight + 360;
|
||||
|
||||
if (scrollPosition.value < 0) {
|
||||
scrollPosition.value = 0;
|
||||
} else if (scrollPosition.value > maxScrollPosition) {
|
||||
scrollPosition.value = maxScrollPosition;
|
||||
}
|
||||
}
|
||||
|
||||
const gridColsClass = computed(() => {
|
||||
const width = window.innerWidth;
|
||||
if (width >= 1200) {
|
||||
return 'grid-cols-4';
|
||||
} else if (width >= 900) {
|
||||
return 'grid-cols-3';
|
||||
} else if (width >= 600) {
|
||||
return 'grid-cols-2';
|
||||
} else {
|
||||
return 'grid-cols-1';
|
||||
}
|
||||
});
|
||||
|
||||
function getCurrentCols() {
|
||||
const width = window.innerWidth;
|
||||
if (width >= 1200) {
|
||||
return 4;
|
||||
} else if (width >= 900) {
|
||||
return 3;
|
||||
} else if (width >= 600) {
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
function editCard(item) {
|
||||
console.log(`Editing card: ${item.title}`);
|
||||
}
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
gridColsClass.value = getCurrentCols();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.hover-card {
|
||||
transition: transform 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.hover-card:hover {
|
||||
transform: scale(1.03); /* Effet de hover restauré */
|
||||
}
|
||||
|
||||
.stars {
|
||||
font-size: 18px; /* Ajustez la taille des icônes */
|
||||
}
|
||||
|
||||
.stars {
|
||||
position: absolute; /* Fixe les étoiles au bas à droite */
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -1,95 +0,0 @@
|
||||
<script setup>
|
||||
import {useSubscriptionStore} from "@/stores/subscriptionStore.js";
|
||||
import {computed, ref} from "vue";
|
||||
import {useBrandingStore} from "@/stores/brandingStore.js";
|
||||
import {useRouter} from "vue-router";
|
||||
|
||||
const router = useRouter()
|
||||
const brandingStore = useBrandingStore()
|
||||
const subscriptionStore = useSubscriptionStore()
|
||||
|
||||
const isSubscribe = computed(() => !subscriptionStore.isSubscribeTo(brandingStore.value.id));
|
||||
|
||||
function subscribeToCreator() {
|
||||
const target = `@${brandingStore.currentBrand}/subscription`;
|
||||
router.push(target)
|
||||
}
|
||||
|
||||
// Référence pour contrôler l'affichage du modal
|
||||
const showUnsubscribeModal = ref(false);
|
||||
|
||||
function unsubscribeFromCreator() {
|
||||
subscriptionStore.unsubscribeFrom(brandingStore.value.id);
|
||||
// Fermer le modal après désabonnement
|
||||
showUnsubscribeModal.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="isSubscribe">
|
||||
<v-btn
|
||||
:style="{
|
||||
width: '150px',
|
||||
height: '28px',
|
||||
backgroundColor: '--h-secondary',
|
||||
color: 'white',
|
||||
borderRadius: '8px',
|
||||
padding: '10px 24px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
transition: 'background-color 0.3s ease'
|
||||
}"
|
||||
@click="subscribeToCreator"
|
||||
>
|
||||
{{ $t('subscribebutton.subscribe') }}
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<v-btn
|
||||
:style="{
|
||||
width: '150px',
|
||||
height: '28px',
|
||||
backgroundColor: '--h-secondary',
|
||||
color: 'white',
|
||||
borderRadius: '0 8px 8px 0',
|
||||
padding: '10px 24px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
transition: 'background-color 0.3s ease'
|
||||
}"
|
||||
@click="showUnsubscribeModal = true"
|
||||
>
|
||||
<div>{{ $t('subscribebutton.unsubscribe') }}</div>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<v-dialog v-model="showUnsubscribeModal" max-width="500">
|
||||
<v-card class="text-center rounded-xl border-2 border-solid border-hSecondary">
|
||||
|
||||
<div class="flex items-center justify-between py-4 text-2xl font-bold border-b mb-2">
|
||||
<div class="flex-1 text-center">
|
||||
Déabonnement
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<v-card-title>Confirmation</v-card-title>
|
||||
<v-card-text>Êtes-vous sûr de vouloir vous désabonner ?</v-card-text>
|
||||
<v-card-actions class="justify-center px-4 pb-4">
|
||||
<v-btn text class="flex-grow-1" variant="outlined"
|
||||
:style="{ backgroundColor: 'rgba(255, 255, 255, 0.1)', color: 'rgba(0, 0, 0, 0.4)' }"
|
||||
@click="unsubscribeFromCreator">Oui
|
||||
</v-btn>
|
||||
|
||||
<v-btn class="flex-grow-1 border-hSecondary text-hOnSecondary"
|
||||
variant="outlined"
|
||||
@click="showUnsubscribeModal = false">
|
||||
Non
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<script setup>
|
||||
import {useSubscriptionStore} from "@/stores/subscriptionStore.js";
|
||||
|
||||
const subscriptionStore = useSubscriptionStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<template v-if="Object.keys(subscriptionStore.subscriptions).length > 0">
|
||||
<template v-for="subscription in subscriptionStore.subscriptions">
|
||||
|
||||
<RouterLink class="capitalize" :to="`/@${subscription.creatorName}`">
|
||||
|
||||
<div class="flex items-center content-center font-sans font-semibold pt-2 ">
|
||||
<img
|
||||
:src="subscription.creatorPortraitUrl"
|
||||
alt="Profile Image"
|
||||
class="rounded-full mx-2"
|
||||
width="32px"
|
||||
height="32px">
|
||||
{{ subscription.creatorName }}
|
||||
</div>
|
||||
|
||||
</RouterLink>
|
||||
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<span>No subscriptions</span>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
@@ -1,82 +0,0 @@
|
||||
<script setup>
|
||||
import {useBrandingStore} from "@/stores/brandingStore.js";
|
||||
import {ref, onMounted} from 'vue';
|
||||
import {useClient} from "@/plugins/api.js";
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
const brandingStore = useBrandingStore();
|
||||
|
||||
const tiers = ref([]);
|
||||
|
||||
// Fetch tiers from API
|
||||
async function fetchTiers() {
|
||||
const client = useClient()
|
||||
const response = await client.get(
|
||||
`/api/membership/tiers/${brandingStore.value.id}`
|
||||
);
|
||||
tiers.value = response.data;
|
||||
}
|
||||
|
||||
// Fetch tiers when the component is mounted
|
||||
onMounted(() => {
|
||||
fetchTiers();
|
||||
});
|
||||
|
||||
const route = useRoute()
|
||||
const baseUrl = window.location.origin;
|
||||
const creatorSlug = route.params.creator_slug || route.path.split('/')[1];
|
||||
const successUrl = `${baseUrl}/${creatorSlug}/content`
|
||||
const cancelledUrl = `${baseUrl}/${creatorSlug}`
|
||||
|
||||
async function doSubscribe(tier) {
|
||||
try {
|
||||
const client = useClient()
|
||||
const response = await client.post(
|
||||
`/api/membership/subscribe`,
|
||||
{
|
||||
creatorId: brandingStore.value.id,
|
||||
tierId: tier.id,
|
||||
checkoutSuccessUrl: successUrl, // TODO: ensure the success-url will insert subscription
|
||||
checkoutCancelledUrl: cancelledUrl
|
||||
})
|
||||
|
||||
window.location.href = response.data.stripeCheckoutUrl;
|
||||
} catch (error) {
|
||||
console.error("Error loading subscriptions:", error);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-container class="d-flex justify-center">
|
||||
<v-row justify="center">
|
||||
|
||||
<v-col
|
||||
:cols="12 / Math.min(tiers.length, 3)"
|
||||
md="4"
|
||||
v-for="tier in tiers"
|
||||
:key="tier.id"
|
||||
>
|
||||
<v-btn @click="doSubscribe(tier)" variant="text">
|
||||
<div class="bg-white shadow-2xl rounded-2xl">
|
||||
<v-img src="/images/hutopymedia/loginpage/loginhutopy.png" class="rounded-t-2xl"></v-img>
|
||||
<div class="pa-6" :style="[Primary, onPrimary]">
|
||||
<v-card-title class="text-h4 text-center py-4 ">{{ tier.name }}</v-card-title>
|
||||
<div class="text-justify">{{ tier.description }}</div>
|
||||
</div>
|
||||
|
||||
<v-card-text class="text-center rounded-b-2xl" :style="[secondaryColor, onSecondaryColor]">
|
||||
<span class="text-h5">{{ tier.price }} $ / par mois</span>
|
||||
</v-card-text>
|
||||
</div>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
Reference in New Issue
Block a user