[dev]creator detail

This commit is contained in:
susie-laptop 2025-05-24 10:40:29 -04:00
parent 7549e0f47b
commit 711c4652bb
4 changed files with 458 additions and 241 deletions

View File

@ -4,10 +4,10 @@ import { fas } from '@fortawesome/free-solid-svg-icons';
import Router from './router';
import './styles/Campaign.scss';
import '@/styles/custom-theme.scss';
import { Chart as ChartJS, ArcElement, Tooltip, Legend, BarElement, LinearScale, CategoryScale } from 'chart.js';
import { Chart as ChartJS, ArcElement, Tooltip, Legend, BarElement, LinearScale, CategoryScale, LineElement, PointElement } from 'chart.js';
import NotificationBar from './components/NotificationBar';
ChartJS.register(ArcElement, Tooltip, Legend, BarElement, LinearScale, CategoryScale);
ChartJS.register(ArcElement, Tooltip, Legend, BarElement, LinearScale, CategoryScale, LineElement, PointElement);
// Add Font Awesome icons to library
library.add(faTiktok, fas, faYoutube, faInstagram);

View File

@ -2,22 +2,18 @@ import { ArrowLeft, Crown, Eye, Heart, Instagram, Link, Mail, MapPin } from 'luc
import { useEffect, useState } from 'react';
import { Card, Table } from 'react-bootstrap';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate, useParams } from 'react-router-dom';
import { clearCreator, fetchCreatorDetail } from '../store/slices/creatorsSlice';
import { Bar, Doughnut } from 'react-chartjs-2';
import { Link as RouterLink, useNavigate, useParams } from 'react-router-dom';
import {
clearCreator,
fetchCreatorDetail,
fetchCreatorFollowers,
fetchCreatorMetrics,
fetchCreatorTrends,
fetchCreatorVideos,
} from '../store/slices/creatorsSlice';
import { Bar, Doughnut, Line } from 'react-chartjs-2';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
const data = {
labels: ['Red', 'Blue', 'Green', 'Purple'],
datasets: [
{
label: 'GMV',
data: [12, 19, 5, 2],
backgroundColor: ['rgba(217, 107, 139)', 'rgba(101, 105, 225)', 'rgba(93, 200, 179)', 'rgba(122, 87, 218)'],
},
],
};
const options = {
plugins: {
legend: {
@ -66,11 +62,18 @@ export default function CreatorDetail({}) {
useEffect(() => {
dispatch(fetchCreatorDetail({ creatorId: id }));
fetchCreatorBaisInfo();
return () => {
dispatch(clearCreator());
};
}, [dispatch, id]);
const fetchCreatorBaisInfo = () => {
dispatch(fetchCreatorMetrics({ creatorId: id }));
dispatch(fetchCreatorFollowers({ creatorId: id }));
dispatch(fetchCreatorTrends({ creatorId: id }));
dispatch(fetchCreatorVideos({ creatorId: id }));
};
const processChartData = (data, chart) => {
switch (chart) {
case 'channel':
@ -284,7 +287,150 @@ export default function CreatorDetail({}) {
}
function CreatorBasicInfo({ selectedCreator }) {
const [activeTab, setActiveTab] = useState('gmv');
useEffect(() => {}, [selectedCreator]);
return (
<div className='creator-basic-info card'>
<div className='basic-info-list'>
<div className='basic-info-title'>Collaboration Metrics</div>
<div className='basic-info-item'>
<div className='value'>
{selectedCreator?.metricsData?.collaboration_metrics?.avg_commission_rate || '--'}
</div>
<div className='name'>Avg. Commission Rate</div>
</div>
<div className='basic-info-item'>
<div className='value'>
{selectedCreator?.metricsData?.collaboration_metrics?.products_count || '--'}
</div>
<div className='name'>Products</div>
</div>
<div className='basic-info-item'>
<div className='value'>
{selectedCreator?.metricsData?.collaboration_metrics?.brand_collaborations || '--'}
</div>
<div className='name'>Brand Collaborations</div>
</div>
<div className='basic-info-item'>
<div className='value'>
{selectedCreator?.metricsData?.collaboration_metrics?.product_price || '--'}
</div>
<div className='name'>Product Price</div>
</div>
</div>
<div className='basic-info-list'>
<div className='basic-info-title'>
Video<span className='time-range'>{selectedCreator?.metricsData?.video?.date_range || '--'}</span>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.video?.gpm || '--'}</div>
<div className='name'>Video GPM</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.video?.videos_count || '--'}</div>
<div className='name'>Videos</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.video?.avg_views || '--'}</div>
<div className='name'>Avg. Video Views</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.video?.avg_engagement || '--'}</div>
<div className='name'>Avg. Video Engagement</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.video?.avg_likes || '--'}</div>
<div className='name'>Avg. Video Likes</div>
</div>
</div>
<div className='basic-info-list'>
<div className='basic-info-title'>
Shoppable Video
<span className='time-range'>
{selectedCreator?.metricsData?.shoppable_video?.date_range || '--'}
</span>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.shoppable_video?.gpm || '--'}</div>
<div className='name'>Video GPM</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.shoppable_video?.videos_count || '--'}</div>
<div className='name'>Videos</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.shoppable_video?.avg_views || '--'}</div>
<div className='name'>Avg. Video Views</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.shoppable_video?.avg_engagement || '--'}</div>
<div className='name'>Avg. Video Engagement</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.shoppable_video?.avg_likes || '--'}</div>
<div className='name'>Avg. Video Likes</div>
</div>
</div>
<div className='basic-info-list'>
<div className='basic-info-title'>
LIVE<span className='time-range'>{selectedCreator?.metricsData?.live?.date_range || '--'}</span>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.live?.gpm || '--'}</div>
<div className='name'>LIVE GPM</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.live?.lives_count || '--'}</div>
<div className='name'>LIVE Videos</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.live?.avg_views || '--'}</div>
<div className='name'>Avg. LIVE Views</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.live?.avg_engagement || '--'}</div>
<div className='name'>Avg. LIVE Engagement</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.live?.avg_likes || '--'}</div>
<div className='name'>Avg. LIVE Likes</div>
</div>
</div>
<div className='basic-info-list'>
<div className='basic-info-title'>
Shoppable LIVE
<span className='time-range'>
{selectedCreator?.metricsData?.shoppable_live?.date_range || '--'}
</span>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.shoppable_live?.gpm || '--'}</div>
<div className='name'>LIVE GPM</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.shoppable_live?.lives_count || '--'}</div>
<div className='name'>LIVE Videos</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.shoppable_live?.avg_views || '--'}</div>
<div className='name'>Avg. LIVE Views</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.shoppable_live?.avg_engagement || '--'}</div>
<div className='name'>Avg. LIVE Engagement</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.metricsData?.shoppable_live?.avg_likes || '--'}</div>
<div className='name'>Avg. LIVE Likes</div>
</div>
</div>
{selectedCreator?.followerData && <CreatorFollowerInfo selectedCreator={selectedCreator} />}
{selectedCreator?.trendsData && <CreatorTrends selectedCreator={selectedCreator} />}
{selectedCreator?.videosData && <CreatorVideos selectedCreator={selectedCreator} />}
</div>
);
}
function CreatorFollowerInfo({ selectedCreator }) {
const barOptions = {
plugins: {
legend: { display: false },
@ -316,160 +462,122 @@ function CreatorBasicInfo({ selectedCreator }) {
},
},
};
const barData = {
labels: ['TX', 'FL', 'NY', 'GE', 'CA'],
const processChartData = (data, chart) => {
switch (chart) {
case 'gender':
return {
labels: Object.keys(data),
datasets: [
{
label: 'Top 5 Locations',
data: [11, 8, 6, 5.5, 5],
backgroundColor: '#6C63FF',
borderRadius: 10,
barPercentage: 0.6,
label: 'Gender',
data: Object.values(data),
backgroundColor: [
'rgba(217, 107, 139)',
'rgba(101, 105, 225)',
'rgba(93, 200, 179)',
'rgba(122, 87, 218)',
],
},
],
};
case 'age':
return {
labels: Object.keys(data),
datasets: [
{
label: 'Age',
data: Object.values(data),
backgroundColor: [
'rgba(217, 107, 139)',
'rgba(101, 105, 225)',
'rgba(93, 200, 179)',
'rgba(122, 87, 218)',
'rgba(234, 145, 110)',
],
},
],
};
case 'location':
return {
labels: Object.keys(data),
datasets: [
{
label: 'Location',
data: Object.values(data),
backgroundColor: [
'rgba(217, 107, 139)',
'rgba(101, 105, 225)',
'rgba(93, 200, 179)',
'rgba(122, 87, 218)',
'rgba(234, 145, 110)',
],
},
],
};
}
};
return (
<div className='creator-basic-info card'>
<div className='basic-info-list'>
<div className='basic-info-title'>Collaboration Metrics</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avg_commission_rate || '--'}</div>
<div className='name'>Avg. Commission Rate</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.products || '--'}</div>
<div className='name'>Products</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.brand_collaborations || '--'}</div>
<div className='name'>Brand Collaborations</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.product_price || '--'}</div>
<div className='name'>Product Price</div>
</div>
</div>
<div className='basic-info-list'>
<div className='basic-info-title'>
Video<span className='time-range'>{selectedCreator?.videoTimeRange || '--'}</span>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgVideoGpm || '--'}</div>
<div className='name'>Video GPM</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.videos?.length || '--'}</div>
<div className='name'>Videos</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgVideoViews || '--'}</div>
<div className='name'>Avg. Video Views</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgVideoEngagements || '--'}</div>
<div className='name'>Avg. Video Engagement</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgVideoLikes || '--'}</div>
<div className='name'>Avg. Video Likes</div>
</div>
</div>
<div className='basic-info-list'>
<div className='basic-info-title'>
Shoppable Video<span className='time-range'>{selectedCreator?.videoTimeRange || '--'}</span>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgVideoGpm || '--'}</div>
<div className='name'>Video GPM</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.videos?.length || '--'}</div>
<div className='name'>Videos</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgVideoViews || '--'}</div>
<div className='name'>Avg. Video Views</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgVideoEngagements || '--'}</div>
<div className='name'>Avg. Video Engagement</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgVideoLikes || '--'}</div>
<div className='name'>Avg. Video Likes</div>
</div>
</div>
<div className='basic-info-list'>
<div className='basic-info-title'>
LIVE<span className='time-range'>{selectedCreator?.liveTimeRange || '--'}</span>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgLiveGpm || '--'}</div>
<div className='name'>LIVE GPM</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.liveVideos || '--'}</div>
<div className='name'>LIVE Videos</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgLiveViews || '--'}</div>
<div className='name'>Avg. LIVE Views</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgLiveEngagements || '--'}</div>
<div className='name'>Avg. LIVE Engagement</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgLiveLikes || '--'}</div>
<div className='name'>Avg. LIVE Likes</div>
</div>
</div>
<div className='basic-info-list'>
<div className='basic-info-title'>
Shoppable LIVE<span className='time-range'>{selectedCreator?.liveTimeRange || '--'}</span>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgLiveGpm || '--'}</div>
<div className='name'>LIVE GPM</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.liveVideos || '--'}</div>
<div className='name'>LIVE Videos</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgLiveViews || '--'}</div>
<div className='name'>Avg. LIVE Views</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgLiveEngagements || '--'}</div>
<div className='name'>Avg. LIVE Engagement</div>
</div>
<div className='basic-info-item'>
<div className='value'>{selectedCreator?.avgLiveLikes || '--'}</div>
<div className='name'>Avg. LIVE Likes</div>
</div>
</div>
<div className='basic-info-list'>
<div className='basic-info-title'>
Follwers<span className='time-range'>{selectedCreator?.liveTimeRange || '--'}</span>
Follwers<span className='time-range'>{selectedCreator?.date_range || '--'}</span>
</div>
<div className='followers-data-charts'>
<div className='data-chart'>
<div className='chart-title'>Follower Gender</div>
<Doughnut data={data} options={{ ...options, cutout: 60 }} />
<Doughnut
data={processChartData(selectedCreator?.followerData?.gender, 'gender')}
options={{ ...options, cutout: 60 }}
/>
</div>
<div className='data-chart'>
<div className='chart-title'>Follower Age</div>
<Doughnut data={data} options={{ ...options, cutout: 60 }} />
<Doughnut
data={processChartData(selectedCreator?.followerData?.age, 'age')}
options={{ ...options, cutout: 60 }}
/>
</div>
<div className='data-chart'>
<div className='chart-title'>Top 5 Locations</div>
<Bar data={barData} options={barOptions} />
<Bar
data={processChartData(selectedCreator?.followerData?.locations, 'location')}
options={barOptions}
/>
</div>
</div>
</div>
);
}
function CreatorTrends({ selectedCreator }) {
const [activeTab, setActiveTab] = useState('gmv');
const lineOptions = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
},
},
};
const processChartData = (tab) => {
return {
labels: selectedCreator?.trendsData?.dates,
datasets: [
{
label: tab,
data: selectedCreator?.trendsData[tab],
fill: false,
borderColor: '#6366f1',
backgroundColor: '#6366f1',
tension: 0.4,
},
],
};
};
return (
<div className='basic-info-list'>
<div className='basic-info-title'>
Trends<span className='time-range'>{selectedCreator?.liveTimeRange || '--'}</span>
@ -482,8 +590,8 @@ function CreatorBasicInfo({ selectedCreator }) {
GMV
</div>
<div
className={`tab-switch-item ${activeTab === 'sold' ? 'active' : ''}`}
onClick={() => setActiveTab('sold')}
className={`tab-switch-item ${activeTab === 'items_sold' ? 'active' : ''}`}
onClick={() => setActiveTab('items_sold')}
>
Items Sold
</div>
@ -494,61 +602,77 @@ function CreatorBasicInfo({ selectedCreator }) {
Followers
</div>
<div
className={`tab-switch-item ${activeTab === 'views' ? 'active' : ''}`}
onClick={() => setActiveTab('views')}
className={`tab-switch-item ${activeTab === 'video_views' ? 'active' : ''}`}
onClick={() => setActiveTab('video_views')}
>
Video Views
</div>
<div
className={`tab-switch-item ${activeTab === 'engagement_rate' ? 'active' : ''}`}
onClick={() => setActiveTab('engagement_rate')}
>
Engagement Rate
</div>
</div>
<div className='line-chart'>
<Line data={processChartData(activeTab)} options={lineOptions} />
</div>
</div>
);
}
function CreatorVideos({ selectedCreator }) {
return (
<div className='basic-info-list video-list'>
<div className='basic-info-title'>Videos</div>
{selectedCreator?.videos?.length > 0 &&
selectedCreator?.videos.map((video) => (
{selectedCreator?.videosData?.regular_videos.total > 0 &&
selectedCreator?.videosData.regular_videos?.videos.map((video) => (
<div className='basic-info-item'>
<div className='picture' style={{ backgroundImage: `url(${video.picture})` }}></div>
<div className='picture' style={{ backgroundImage: `url(${video.thumbnail_url})` }}></div>
<div className='right-side-info'>
<Crown size={16} />
<div className='video-title'>{video.title}</div>
<Crown size={16} className='crown-icon' />
<RouterLink to={video.video_url} className='video-title text-dark'>
{video.title}
</RouterLink>
<div className='release-time item-info'>
Release Time<span className='time'>{video.releaseTime}</span>
Release Time<span className='time'>{video.release_date}</span>
</div>
<div className='views item-info'>
<FontAwesomeIcon icon='fa-solid fa-eye' style={{ color: '#636AE8FF' }} />
{video.views}
{video.view_count}
</div>
<div className='like item-info'>
<FontAwesomeIcon icon='fa-solid fa-heart' style={{ color: '#E8618CFF' }} />
{video.likes}
{video.like_count}
</div>
</div>
</div>
))}
<div className='basic-info-title'>Videos with Product</div>
{selectedCreator?.videosWithProduct?.length > 0 &&
selectedCreator?.videosWithProduct.map((video) => (
{selectedCreator?.videosData?.product_videos?.total > 0 &&
selectedCreator?.videosData?.product_videos?.videos.map((video) => (
<div className='basic-info-item'>
<div className='picture' style={{ backgroundImage: `url(${video.picture})` }}></div>
<div className='picture' style={{ backgroundImage: `url(${video.thumbnail_url})` }}></div>
<div className='right-side-info'>
<Crown size={16} className='crown-icon' />
<div className='video-title'>{video.title}</div>
<RouterLink to={video.video_url} className='video-title text-dark'>
{video.title}
</RouterLink>
<div className='release-time item-info'>
Release Time<span className='time'>{video.releaseTime}</span>
Release Time<span className='time'>{video.release_date}</span>
</div>
<div className='views item-info'>
<FontAwesomeIcon icon='fa-solid fa-eye' style={{ color: '#636AE8FF' }} />
{video.views}
{video.view_count}
</div>
<div className='like item-info'>
<FontAwesomeIcon icon='fa-solid fa-heart' style={{ color: '#E8618CFF' }} />
{video.likes}
{video.like_count}
</div>
</div>
</div>
))}
</div>
</div>
);
}

View File

@ -262,7 +262,7 @@ export const fetchPrivateCreators = createAsyncThunk(
export const fetchCreatorDetail = createAsyncThunk(
'creators/fetchCreatorDetail',
async ({ creatorId }, { getState, rejectWithValue }) => {
async ({ creatorId }, { dispatch, rejectWithValue }) => {
try {
const response = await api.get(`/daren_detail/creators/${creatorId}`);
if (response.code === 200) {
@ -270,6 +270,71 @@ export const fetchCreatorDetail = createAsyncThunk(
} else {
throw new Error(response.message);
}
} catch (error) {
console.log('fetchCreatorDetail.rejected', error);
return rejectWithValue(error.message);
}
}
);
export const fetchCreatorMetrics = createAsyncThunk(
'creators/fetchCreatorMetrics',
async ({ creatorId }, { rejectWithValue }) => {
try {
const response = await api.get(`/daren_detail/creators/${creatorId}/metrics`);
if (response.code === 200 || response.code === 201) {
return response;
} else {
throw new Error(response.message);
}
} catch (error) {
return rejectWithValue(error.message);
}
}
);
export const fetchCreatorFollowers = createAsyncThunk(
'creators/fetchCreatorFollowers',
async ({ creatorId }, { rejectWithValue }) => {
try {
const response = await api.get(`/daren_detail/creator/${creatorId}/followers`);
if (response.code === 200) {
return response;
} else {
throw new Error(response.message);
}
} catch (error) {
return rejectWithValue(error.message);
}
}
);
export const fetchCreatorTrends = createAsyncThunk(
'creators/fetchCreatorTrends',
async ({ creatorId }, { rejectWithValue }) => {
try {
const response = await api.get(`/daren_detail/creator/${creatorId}/trends`);
if (response.code === 200) {
return response;
} else {
throw new Error(response.message);
}
} catch (error) {
return rejectWithValue(error.message);
}
}
);
export const fetchCreatorVideos = createAsyncThunk(
'creators/fetchCreatorVideos',
async ({ creatorId }, { rejectWithValue }) => {
try {
const response = await api.get(`/daren_detail/creator/${creatorId}/videos`);
if (response.code === 200) {
return response;
} else {
throw new Error(response.message);
}
} catch (error) {
return rejectWithValue(error.message);
}
@ -285,7 +350,9 @@ export const addCreatorsToCampaign = createAsyncThunk(
campaign_id: campaignId,
});
if (response.code === 200) {
dispatch(setNotificationBarMessage({ message: 'Creators added to campaign successfully', type: 'success' }));
dispatch(
setNotificationBarMessage({ message: 'Creators added to campaign successfully', type: 'success' })
);
return response;
} else {
dispatch(setNotificationBarMessage({ message: response.message, type: 'error' }));
@ -395,6 +462,18 @@ const creatorsSlice = createSlice({
.addCase(fetchCreatorDetail.rejected, (state, action) => {
state.status = 'failed';
state.error = action.error.message;
})
.addCase(fetchCreatorMetrics.fulfilled, (state, action) => {
state.selectedCreator.metricsData = action.payload.data;
})
.addCase(fetchCreatorFollowers.fulfilled, (state, action) => {
state.selectedCreator.followerData = action.payload.data;
})
.addCase(fetchCreatorTrends.fulfilled, (state, action) => {
state.selectedCreator.trendsData = action.payload.data;
})
.addCase(fetchCreatorVideos.fulfilled, (state, action) => {
state.selectedCreator.videosData = action.payload.data;
});
},
});

View File

@ -56,12 +56,15 @@
display: flex;
flex-flow: column nowrap;
gap: 1rem;
height: 100%;
.creator-info-detail-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 1rem;
justify-content: space-between;
height: calc(100% - 1.5rem);
overflow-y: auto;
.creator-info-container {
flex: 4;
@ -320,6 +323,13 @@
flex-flow: column nowrap;
gap: 0.5rem;
font-size: 0.875rem;
height: 178px;
justify-content: flex-start;
.crown-icon {
margin-bottom: 0.5rem;
color: $danger-500;
}
.video-title {
font-weight: 700;
text-overflow: ellipsis;
@ -343,6 +353,10 @@
}
}
}
.line-chart {
width: 100%;
height: 250px;
}
}
.collab-info {
width: 100%;