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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.2] - 2026-04-16
## [1.1.0] - 2026-04-16

## Added

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "api-market",
"version": "1.0.2",
"version": "1.1.0",
"private": true,
"dependencies": {
"@asyncapi/react-component": "^3.0.0",
Expand Down
6 changes: 6 additions & 0 deletions public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@
"news": "News",
"newsDescription": "Discover all the news about technology, APIs, and digital transformation",
"seeMore": "See more",
"badgesTitle": "API Quality Certifications",
"badgeSecurity": "Security",
"badgeQuality": "Quality",
"badgeDevExperience": "Developer Experience",
"badgeDora": "DORA Compliance",
"badgeOpenFinance": "Open Finance Compliance",
"globalGradesTitle": "Global grades of the API",
"globalGradesSubtitle": "Overall quality and readiness indicators",
"ratingGlobal": "Global",
Expand Down
6 changes: 6 additions & 0 deletions public/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@
"news": "Novedades",
"newsDescription": "Conoce todas las novedades sobre tecnología, APIs y transformación digital",
"seeMore": "Ver más",
"badgesTitle": "Certificaciones de Calidad de API",
"badgeSecurity": "Seguridad",
"badgeQuality": "Calidad",
"badgeDevExperience": "Experiencia de Desarrollo",
"badgeDora": "Cumplimiento DORA",
"badgeOpenFinance": "Cumplimiento Open Finance",
"globalGradesTitle": "Calificaciones globales de la API",
"globalGradesSubtitle": "Indicadores generales de calidad y disponibilidad",
"ratingGlobal": "Global",
Expand Down
139 changes: 139 additions & 0 deletions src/pages/public/ApiDetail/api-detail.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -416,3 +416,142 @@
margin-top: 40px !important;
margin-bottom: 40px !important;
}

.ratings__wrapper {
background: #fff;
border-radius: 12px;
padding: 24px 16px;
border-bottom: 1px solid #eee;
text-align: center;
margin: 0 0 100px 0;
}

.ratings__title {
font-size: clamp(22px, 3.5vw, 35px);
font-weight: 700;
margin-bottom: clamp(12px, 2vw, 20px);
color: #222;
}

.ratings__subtitle {
font-size: clamp(13px, 1.8vw, 17px);
color: #777;
margin-bottom: clamp(16px, 3vw, 28px);
}

.ratings__grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: clamp(6px, 1.2vw, 12px);
justify-items: center;
max-width: 700px;
margin: 0 auto;
}

.rating__item {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;

span {
font-size: clamp(11px, 1.2vw, 14px);
font-weight: 700;
letter-spacing: 0.2px;
color: #555;
}
}

.rating__circle {
width: clamp(54px, 6vw, 64px);
height: clamp(54px, 6vw, 64px);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: clamp(16px, 2vw, 22px);
font-weight: 800;
color: #fff;
}

.rating__A {
background: #27ae60;
}

.rating__B {
background: #b0d226;
}

.rating__C {
background: #f1c40f;
}

.rating__D {
background: #f39c12;
}

.rating__E {
background: #d52c19;
}

.rating__empty {
background: #fff;
border: 1px solid #000;
color: #000;
opacity: 0.6;
}

.section__badges {
padding-bottom: 2rem;
border-bottom: 1px solid #eee;
margin-top: 40px !important;
margin-bottom: 40px !important;
}

.badges__wrapper {
text-align: center;
}

.badges__grid {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: clamp(20px, 4vw, 40px);
margin-top: 2rem;
}

.badge__item {
display: flex;
flex-direction: column;
align-items: center;
max-width: 120px;
transition: transform 0.3s ease;

&:hover {
transform: translateY(-5px);
}
}

.badge__img {
width: clamp(80px, 10vw, 110px);
height: auto;
margin-bottom: 10px;
filter: drop-shadow(0px 4px 8px rgba(0,0,0,0.1));
}

.badge__label {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
color: #666;
line-height: 1.2;
}

@media (max-width: 1024px) {
.ratings__grid {
grid-template-columns: repeat(2, 1fr);
max-width: 700px;
padding: 0 clamp(16px, 5vw, 50px);
gap: clamp(16px, 4vw, 24px);
}
}
82 changes: 78 additions & 4 deletions src/pages/public/ApiDetail/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ import { getLibrary, getLibraries } from '../../../redux/actions/libraryAction';
import { getBlogs } from '../../../redux/actions/blogAction';
import config from '../../../services/config';
import classes from './api-detail.module.scss';
import apiSecurity from '../../../static/img/badges/apis-security.png';
import apiQuality from '../../../static/img/badges/apis-quality.png';
import apiExperience from '../../../static/img/badges/apis-experience.png';
import apiDora from '../../../static/img/badges/apis-dora.png';
import apiOpenfinance from '../../../static/img/badges/apis-openfinance.png';

import asyncSecurity from '../../../static/img/badges/asyncapi-security.png';
import asyncQuality from '../../../static/img/badges/asyncapi-quality.png';
import asyncExperience from '../../../static/img/badges/asyncapi-experience.png';
import asyncDora from '../../../static/img/badges/asyncapi-dora.png';
import asyncOpenfinance from '../../../static/img/badges/asyncapi-openfinance.png';
import Ratings from '../../../components/Ratings';

function ApiDetail({ setIsOpen }) {
Expand Down Expand Up @@ -135,10 +146,51 @@ function ApiDetail({ setIsOpen }) {
const apisNews = shuffledApis.slice(0, 3);

const hasAnyRating =
!!library?.ratings?.globalRating ||
!!library?.ratings?.definitionRating ||
!!library?.ratings?.securityRating ||
!!library?.ratings?.qualityRating;
!!library?.globalRating ||
!!library?.definitionRating ||
!!library?.securityRating ||
!!library?.qualityRating;

const hasAnyBadge =
!!library?.devExperienceCheck ||
!!library?.securityCheck ||
!!library?.qualityCheck ||
!!library?.doraCheck ||
!!library?.openFinanceCheck;

const isAsync = library?.openDocType === 'asyncapi';
const badgeConfig = [
{
key: 'securityCheck',
label: t('ApiDetail.badgeSecurity'),
img: isAsync ? asyncSecurity : apiSecurity
},
{
key: 'qualityCheck',
label: t('ApiDetail.badgeQuality'),
img: isAsync ? asyncQuality : apiQuality
},
{
key: 'devExperienceCheck',
label: t('ApiDetail.badgeDevExperience'),
img: isAsync ? asyncExperience : apiExperience
},
{
key: 'doraCheck',
label: t('ApiDetail.badgeDora'),
img: isAsync ? asyncDora : apiDora
},
{
key: 'openFinanceCheck',
label: t('ApiDetail.badgeOpenFinance'),
img: isAsync ? asyncOpenfinance : apiOpenfinance
}
];

const getRatingClass = (rating) => {
if (!rating) return classes.rating__empty;
return classes[`rating__${rating}`] || classes.rating__empty;
};

const handleClickPage = (id) => {
dispatch(getLibrary(id));
Expand All @@ -161,6 +213,28 @@ function ApiDetail({ setIsOpen }) {
/>
</section>
<section className={`container ${classes.section__content} pb-9`}>&nbsp;</section>
{library && hasAnyBadge && (
<section className={`container ${classes.section__content} ${classes.section__badges}`}>
<div className={classes.badges__wrapper}>
<h2 className={classes.ratings__title}>{t('ApiDetail.badgesTitle')}</h2>
<div className={classes.badges__grid}>
{badgeConfig.map((badge) => (
library[badge.key] && (
<div key={badge.key} className={classes.badge__item}>
<img
src={badge.img}
alt={badge.label}
title={badge.label}
className={classes.badge__img}
/>
<span className={classes.badge__label}>{badge.label}</span>
</div>
)
))}
</div>
</div>
</section>
)}
{library && hasAnyRating && (
<section className={`container ${classes.section__content} ${classes.section__ratings}`}>
<Ratings
Expand Down
Binary file added src/static/img/badges/apis-dora.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/static/img/badges/apis-experience.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/static/img/badges/apis-openfinance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/static/img/badges/apis-quality.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/static/img/badges/apis-security.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/static/img/badges/asyncapi-dora.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/static/img/badges/asyncapi-experience.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/static/img/badges/asyncapi-openfinance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/static/img/badges/asyncapi-quality.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/static/img/badges/asyncapi-security.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.