Improved additional info to display for each listing

This commit is contained in:
Alicia Sykes 2024-03-01 18:04:06 +00:00
parent afb5c8f830
commit 3b8bd7b44b
3 changed files with 173 additions and 16 deletions

View File

@ -28,7 +28,7 @@ const getIconName = (clasification: string) => {
{(priv.points && priv.points.length) > 0 && ( {(priv.points && priv.points.length) > 0 && (
<div class="left"> <div class="left">
<h4>Privacy Policy Summary</h4> <h4>Privacy Policy Summary</h4>
<ul> <ul class="no-point">
{priv.points.map((point) => ( {priv.points.map((point) => (
<li class={`clasification ${point.case.classification}`}> <li class={`clasification ${point.case.classification}`}>
<FontAwesome iconName={getIconName(point.case.classification)} /> <FontAwesome iconName={getIconName(point.case.classification)} />
@ -70,8 +70,11 @@ const getIconName = (clasification: string) => {
)} )}
{priv.points && priv.points.length > 0 && ( {priv.points && priv.points.length > 0 && (
<h4>About the Data</h4> <h4>About the Data</h4>
<p>This data is kindly provided by <a href="https://tosdr.org/">tosdr.org</a></p> <p class="about-tosdr">
<p>View the full report at: <a href={`https://tosdr.org/en/service/${priv.id}`}>tosdr.org/en/service/{priv.id}</a></p> This data is kindly provided by <a href="https://tosdr.org/">tosdr.org</a>.
Read full report at: <a href={`https://tosdr.org/en/service/${priv.id}`}>#{priv.id}</a>
</p>
)} )}
</div> </div>
</div> </div>
@ -111,6 +114,7 @@ h4 {
li { li {
:global(svg) { :global(svg) {
width: 1rem; width: 1rem;
margin-right: 0.2rem;
} }
&.clasification { &.clasification {
&.good :global(svg) { color: #35b969; } &.good :global(svg) { color: #35b969; }
@ -137,6 +141,10 @@ h4 {
opacity: 0.7; opacity: 0.7;
} }
} }
&.no-point {
list-style: none;
padding-left: 0.25rem;
}
} }
.rating { .rating {
@ -158,4 +166,10 @@ h4 {
color: var(--rating-color); color: var(--rating-color);
border-color: var(--rating-color); border-color: var(--rating-color);
} }
.about-tosdr {
display: inline;
font-size: 0.8rem;
opacity: 0.7;
}
</style> </style>

View File

@ -12,6 +12,8 @@ import { fetchGitHubStats } from '@utils/fetch-repo-info';
import { fetchTosdrPrivacy } from '@utils/fetch-privacy-policy'; import { fetchTosdrPrivacy } from '@utils/fetch-privacy-policy';
import { fetchWebsiteInfo } from '@utils/fetch-website-info'; import { fetchWebsiteInfo } from '@utils/fetch-website-info';
import { parseMarkdown, formatLink } from '@utils/parse-markdown'; import { parseMarkdown, formatLink } from '@utils/parse-markdown';
import FontAwesome from '@components/form/FontAwesome.svelte';
import Button from '@components/form/Button.astro';
interface Props extends Service { interface Props extends Service {
slug: string; slug: string;
@ -27,9 +29,9 @@ const {
tosdrId, tosdrId,
icon, icon,
followWith, followWith,
// securityAudited, securityAudited,
// openSource, openSource,
// acceptsCrypto, acceptsCrypto,
parentSection, parentSection,
categoryName, categoryName,
} = Astro.props; } = Astro.props;
@ -103,14 +105,15 @@ export async function getStaticPaths() {
}); });
} }
// const makePaginationLinks = () => { const makePaginationLinks = () => {
// const index = otherSections.findIndex(section => section.name === title); const allServices = parentSection.services || [];
// const previousSection = index > 0 ? otherSections[index - 1].name : null; const index = allServices.findIndex(item => item.name === name);
// const nextSection = index < otherSections.length - 1 ? otherSections[index + 1].name : null; const previousItem = index > 0 ? allServices[index - 1].name : null;
// return { previous: previousSection, next: nextSection }; const nextItem = index < allServices.length - 1 ? allServices[index + 1].name : null;
// }; return { previous: previousItem, next: nextItem };
};
// const { previous, next } = makePaginationLinks(); const { previous, next } = makePaginationLinks();
const ignoredSites = ['github.gom', 'wikipedia.']; const ignoredSites = ['github.gom', 'wikipedia.'];
@ -151,7 +154,63 @@ const websiteData = (url && !ignoredSites.some(ignoredSite => url.includes(ignor
data-service-url={formatLink(url)} data-service-url={formatLink(url)}
src={icon || `https://icon.horse/icon/${formatLink(url)}`} src={icon || `https://icon.horse/icon/${formatLink(url)}`}
/> />
<div>
<p class="description" set:html={parseMarkdown(description)}></p> <p class="description" set:html={parseMarkdown(description)}></p>
<ul>
{ url && (
<li>
<b>Homepage:</b>
<a href={url}>{formatLink(url)}</a>
</li>
)}
{ github && (
<li>
<b>GitHub:</b>
<a href={`https://github.com/${github}`}>github.com/{github}</a>
</li>
)}
{ tosdrId && (
<li>
<b>ToS;DR:</b>
<a href={`https://tosdr.org/en/service/${tosdrId}`}>{`tosdr.org/en/service/${tosdrId}`}</a>
</li>
)}
{ url && (
<li>
<b>Web info:</b>
<a href={`https://web-check.xyz/results/${formatLink(url)}`}>{`web-check.xyz/results/${formatLink(url)}`}</a>
</li>
)}
</ul>
</div>
</div>
<div class="highlights">
{ securityAudited && (
<span class="meta-item great" title={`${name} has been security audited by an accredited auditor, with results published publicly`}>
<FontAwesome iconName="securityAudited" /> Security Audited
</span>
)}
{ acceptsCrypto && (
<span class="meta-item great" title={`${name} accepts anonymous payment methods`}>
<FontAwesome iconName="cryptoAccepted" /> Crypto Payments Accepted
</span>
)}
{ securityAudited === false && (
<span class="meta-item warning" title={`${name} has not been audited`}>
<FontAwesome iconName="notSecurityAudited" /> No Security Audit
</span>
)}
{ (openSource === false) && (
<span class="warning">
<FontAwesome iconName="closedSource" />
Not Open Source
</span>
)}
{ openSource || (github && openSource !== false) ? (
<span class="meta-item great" title={`${name} is open source`}>
<FontAwesome iconName="openSource" /> Open Source
</span>
) : null }
</div> </div>
</section> </section>
{ privacyData && ( { privacyData && (
@ -188,6 +247,24 @@ const websiteData = (url && !ignoredSites.some(ignoredSite => url.includes(ignor
sectionName={parentSection.name} sectionName={parentSection.name}
/> />
</section> </section>
<div class="pagination-navigation">
{ previous ? (
<Button url={`/${slugify(categoryName)}/${slugify(parentSection.name)}/${slugify(previous)}`}>
<span>← Previous</span>
<p>{previous}</p>
</Button>
) : <p class="nothing"></p>}
<a href={`/${slugify(categoryName)}/${slugify(parentSection.name)}`} class="go-to-category">
View {parentSection.name} ({(parentSection.services || []).length})
</a>
{ next && (
<Button url={`/${slugify(categoryName)}/${slugify(parentSection.name)}/${slugify(next)}`}>
<span>Next →</span>
<p>{next}</p>
</Button>
)}
</div>
</main> </main>
</Layout> </Layout>
@ -261,10 +338,29 @@ h3 {
.intro { .intro {
font-size: 1.2rem; font-size: 1.2rem;
font-style: italic; font-style: italic;
opacity: 0.7; opacity: 0.9;
display: flex; display: flex;
align-items: center;
gap: 0.5rem; gap: 0.5rem;
.service-icon {
border-radius: var(--curve-md);
margin-top: 1rem;
}
h4 {
margin-bottom: 0;
}
ul {
padding-left: 1rem;
list-style: circle;
font-style: normal;
font-size: 1rem;
margin-top: 0;
b {
font-size: 1rem;
font-weight: 400;
min-width: 85px;
display: inline-block;
}
}
} }
.pagination-navigation { .pagination-navigation {
@ -343,4 +439,51 @@ h3 {
} }
} }
.highlights {
display: flex;
gap: 1rem;
flex-wrap: wrap;
align-items: center;
justify-content: end;
.meta-item, .warning {
display: flex;
align-items: center;
// justify-content: center;
gap: 0.25rem;
opacity: 0.6;
font-size: 0.9rem;
padding: 0.5rem 0;
:global(svg) {
color: var(--foreground);
width: 1.2rem;
height: 1.2rem;
}
a {
text-decoration: none;
color: var(--foreground);
display: flex;
gap: 0.25rem;
&:hover {
color: var(--accent-3);
:global(svg) {
color: var(--accent-3);
}
}
}
}
.warning {
color: var(--danger);
:global(svg) {
color: var(--danger);
}
}
.great {
color: #007930; // var(--success);
:global(svg) {
color: #007930; // var(--success);
}
}
}
</style> </style>

View File

@ -1,6 +1,6 @@
export const fetchTosdrPrivacy = async (serviceId: string): Promise<PrivacyPolicyResponse | null> => { export const fetchTosdrPrivacy = async (serviceId: string): Promise<PrivacyPolicyResponse | null> => {
const endpoint = `https://api.tosdr.org/service/v2?id=${serviceId}`; const endpoint = `https://privacy-policies.as93.workers.dev/${serviceId}`;
try { try {
return await fetch(endpoint).then((res) => res.json()); return await fetch(endpoint).then((res) => res.json());
} catch (error) { } catch (error) {