mirror of
https://github.com/Lissy93/web-check.git
synced 2025-08-16 23:51:11 +02:00
Determines technologies used on a given site
This commit is contained in:
114
src/components/Results/TechStack.tsx
Normal file
114
src/components/Results/TechStack.tsx
Normal file
@ -0,0 +1,114 @@
|
||||
|
||||
import styled from 'styled-components';
|
||||
import { Card } from 'components/Form/Card';
|
||||
import Heading from 'components/Form/Heading';
|
||||
import Row, { ExpandableRow, RowProps } from 'components/Form/Row';
|
||||
import colors from 'styles/colors';
|
||||
|
||||
const cardStyles = `
|
||||
grid-row: span 2;
|
||||
small {
|
||||
margin-top: 1rem;
|
||||
opacity: 0.5;
|
||||
display: block;
|
||||
a { color: ${colors.primary}; }
|
||||
}
|
||||
`;
|
||||
|
||||
const TechStackRow = styled.div`
|
||||
transition: all 0.2s ease-in-out;
|
||||
.r1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
h4 {
|
||||
margin: 0.5rem 0 0 0;
|
||||
}
|
||||
.r2 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.tech-version {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.tech-confidence, .tech-categories {
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.tech-confidence {
|
||||
display: none;
|
||||
}
|
||||
.tech-description, .tech-website {
|
||||
font-size: 0.8rem;
|
||||
margin: 0.25rem 0;
|
||||
font-style: italic;
|
||||
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
&.tech-website {
|
||||
-webkit-line-clamp: 1;
|
||||
}
|
||||
a {
|
||||
color: ${colors.primary};
|
||||
opacity: 0.75;
|
||||
&:hover { opacity: 1; }
|
||||
}
|
||||
}
|
||||
.tech-icon {
|
||||
width: 2.5rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid ${colors.primary};
|
||||
}
|
||||
&:hover {
|
||||
.tech-confidence {
|
||||
display: block;
|
||||
}
|
||||
.tech-categories {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const TechStackCard = (props: {data: any, title: string, actionButtons: any }): JSX.Element => {
|
||||
const technologies = props.data.technologies;
|
||||
const iconsCdn = 'https://raw.githubusercontent.com/wappalyzer/wappalyzer/master/src/drivers/webextension/images/icons/';
|
||||
return (
|
||||
<Card heading={props.title} actionButtons={props.actionButtons} styles={cardStyles}>
|
||||
{technologies.map((tech: any, index: number) => {
|
||||
return (
|
||||
<TechStackRow>
|
||||
<div className="r1">
|
||||
<Heading as="h4" size="small">
|
||||
{tech.name}
|
||||
<span className="tech-version">{tech.version? `(v${tech.version})` : ''}</span>
|
||||
</Heading>
|
||||
<span className="tech-confidence" title={`${tech.confidence}% certain`}>Certainty: {tech.confidence}%</span>
|
||||
<span className="tech-categories">
|
||||
{tech.categories.map((cat: any, i: number) => `${cat.name}${i < tech.categories.length - 1 ? ', ' : ''}`)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="r2">
|
||||
<img className="tech-icon" width="10" src={`${iconsCdn}${tech.icon}`} alt={tech.name} />
|
||||
<div>
|
||||
<p className="tech-description">{tech.description}</p>
|
||||
<p className="tech-website">Learn more at: <a href={tech.website}>{tech.website}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</TechStackRow>
|
||||
);
|
||||
})}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default TechStackCard;
|
Reference in New Issue
Block a user