Skip to content
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
17 changes: 0 additions & 17 deletions website/modules/asset/ui/src/scss/_animation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,3 @@
filter: blur(0);
}
}

@keyframes tagSlideIn {
0% {
opacity: 0;
max-height: 0;
transform: translateY(-10px);
}
50% {
opacity: 0.5;
transform: translateY(-5px);
}
100% {
opacity: 1;
max-height: 50px;
transform: translateY(0);
}
}
138 changes: 138 additions & 0 deletions website/modules/asset/ui/src/scss/_cases.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,144 @@
}
}

// Case Study Navigation
.cs_nav-container {
display: flex;
flex-direction: row;
justify-content: space-between;
}

.cs_back-link {
font-weight: $font-weight-300;
font-size: 11px;
line-height: 120%;
text-decoration: none;
display: flex;
flex-direction: row;
align-items: center;
padding: 0px;
gap: 8px;
color: $gray-300;
@include breakpoint-medium {
gap: 12px;
}
&:hover {
text-decoration: underline;
cursor: pointer;
}

.cs_back-arrow {
transition: opacity 0.2s ease;
flex-shrink: 0;

&--desktop {
display: none;

@include breakpoint-medium {
display: block;
}
}

&--mobile {
display: block;

@include breakpoint-medium {
display: none;
}
}
}
}

.cs_navigation {
display: flex;
flex-direction: row;
align-items: center;
padding: 0;
gap: 20px;
@include breakpoint-medium {
gap: 44px;
}
}

.cs_nav-item {
display: flex;
flex-direction: row;
align-items: center;
padding: 0;
gap: 12px;
height: 13px;
flex: none;
flex-grow: 0;
}

.cs_nav-link {
display: flex;
flex-direction: row;
align-items: center;
gap: 12px;
font-weight: $font-weight-300;
font-size: 11px;
line-height: 120%;
text-decoration: none;
transition: all 0.2s ease;

&--active {
color: $gray-500;

&:hover {
text-decoration: underline;

.cs_nav-arrow[src*='arrow-left'] {
opacity: 0.7;
transform: translateX(2px);
}

.cs_nav-arrow[src*='arrow-right'] {
opacity: 0.7;
transform: translateX(-2px);
}
}

.cs_nav-arrow {
opacity: 1;
}
}

&--disabled {
color: $gray-300;
cursor: default;

.cs_nav-arrow {
opacity: 0.4;
}
}
}

.cs_nav-arrow {
transition: all 0.2s ease;
flex-shrink: 0;
}

.cs_nav-text {
display: none;

@include breakpoint-medium {
display: block;
}
}

// Keyframes for smooth animations
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

// Animation for reduced motion users (accessibility)
@media (prefers-reduced-motion: reduce) {
.cs_grid,
Expand Down
115 changes: 32 additions & 83 deletions website/modules/case-studies-page/index.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,7 @@
const mainWidgets = require('../../lib/mainWidgets');
const DEFAULT_VISIBLE_TAGS_COUNT = 5;

// Helper utility functions for tag counting
const tagCountHelpers = {
createTagMap(casesTags) {
const tagMap = {};
casesTags.forEach((tag) => {
tagMap[tag.aposDocId] = tag.slug;
});
return tagMap;
},

countTagsOfType(tagIds, tagMap, countsForType) {
if (!tagIds?.length) {
return;
}
tagIds.forEach((tagId) => {
const tagSlug = tagMap[tagId];
if (tagSlug && !countsForType[tagSlug]) {
countsForType[tagSlug] = 0;
}
if (tagSlug) {
countsForType[tagSlug] += 1;
}
});
},

async fetchCaseStudiesAndTags(req, aposModules, options) {
const caseStudies = await aposModules[options.pieces].find(req).toArray();
const casesTags = await aposModules['cases-tags'].find(req).toArray();
return [caseStudies, casesTags];
},

processCaseStudies(caseStudies, tagMap, tagCounts) {
caseStudies.forEach((study) => {
this.countTagsOfType(study.industryIds, tagMap, tagCounts.industry);

this.countTagsOfType(study.stackIds, tagMap, tagCounts.stack);

this.countTagsOfType(
study.caseStudyTypeIds,
tagMap,
tagCounts.caseStudyType,
);
});
},
};
const TagCountService = require('./services/TagCountService');
const NavigationService = require('./services/NavigationService');
const UrlService = require('./services/UrlService');

module.exports = {
extend: '@apostrophecms/piece-page-type',
Expand Down Expand Up @@ -79,53 +35,46 @@ module.exports = {

init(self) {
self.beforeIndex = async (req) => {
try {
const tagCounts = await self.calculateTagCounts(req);

const reqCopy = req;
if (!reqCopy.data) {
reqCopy.data = {};
}
reqCopy.data.tagCounts = tagCounts;
reqCopy.data.defaultVisibleTagsCount = DEFAULT_VISIBLE_TAGS_COUNT;
} catch (error) {
self.apos.util.error('Error calculating tag counts:', error);
await self.setupIndexData(req);
};

const reqCopy = req;
if (!reqCopy.data) {
reqCopy.data = {};
}
reqCopy.data.tagCounts = {
industry: {},
stack: {},
caseStudyType: {},
};
reqCopy.data.defaultVisibleTagsCount = DEFAULT_VISIBLE_TAGS_COUNT;
}
self.beforeShow = async (req) => {
await self.setupShowData(req);
};
},

methods(self) {
return {
async calculateTagCounts(req) {
const tagCounts = {
industry: {},
stack: {},
caseStudyType: {},
};

const [caseStudies, casesTags] =
await tagCountHelpers.fetchCaseStudiesAndTags(
async setupIndexData(req) {
try {
const tagCounts = await TagCountService.calculateTagCounts(
req,
self.apos.modules,
self.options,
);
UrlService.attachIndexData(req, tagCounts);
} catch (error) {
self.apos.util.error('Error calculating tag counts:', error);
UrlService.attachIndexData(req, {
industry: {},
stack: {},
caseStudyType: {},
});
}
},

const tagMap = tagCountHelpers.createTagMap(casesTags);

tagCountHelpers.processCaseStudies(caseStudies, tagMap, tagCounts);

return tagCounts;
async setupShowData(req) {
try {
const navigation = await NavigationService.getNavigationDataForPage(
req,
self.apos,
self,
);
UrlService.attachShowData(req, navigation);
} catch (error) {
self.apos.util.error('Error calculating navigation data:', error);
UrlService.attachShowData(req, { prev: null, next: null });
}
},
};
},
Expand Down
Loading
Loading