parent
c663c9a0aa
commit
d6a5c86c5e
9 changed files with 240 additions and 232 deletions
@ -0,0 +1,21 @@ |
||||
.TypeField { |
||||
font-size: 0.8em; |
||||
font-weight: 700; |
||||
} |
||||
|
||||
.ResultsList { |
||||
padding: 3px 0px; |
||||
margin: 6px 0px; |
||||
} |
||||
|
||||
.ScoreField { |
||||
border-radius: 3px; |
||||
background-color: #ccc; |
||||
padding: 6px 8px; |
||||
display: inline-block; |
||||
width: 3.5em; |
||||
text-align: center; |
||||
font-family: 'Arvo Gruen', 'Arvo', sans-serif; |
||||
font-size: 120%; |
||||
color: #333; |
||||
} |
@ -0,0 +1,205 @@ |
||||
/** |
||||
* The ResultsTable component is a table of results for all websites we checked. |
||||
*/ |
||||
|
||||
import React, { Component } from 'react'; |
||||
import { Link } from "react-router-dom"; |
||||
import './ResultsList.css'; |
||||
import punycode from 'punycode'; |
||||
import chroma from 'chroma-js'; |
||||
|
||||
|
||||
class ScoreField extends Component { |
||||
render() { |
||||
var ratio = this.props.score / this.props.maxScore; |
||||
var bg = chroma.mix('#8D5335', '#75B66B', ratio); |
||||
return <span className='ScoreField' style={{backgroundColor: bg.hex()}}>{ this.props.score }</span>; |
||||
} |
||||
} |
||||
|
||||
class StateField extends Component { |
||||
render() { |
||||
var label = this.props.state; |
||||
|
||||
switch (this.props.state) { |
||||
case 'Nordrhein-Westfalen': |
||||
label = 'NW'; |
||||
break; |
||||
case 'Rheinland-Pfalz': |
||||
label = 'RP'; |
||||
break; |
||||
case 'Niedersachsen': |
||||
label = 'NS'; |
||||
break; |
||||
case 'Baden-Württemberg': |
||||
label = 'BW'; |
||||
break; |
||||
case 'Bayern': |
||||
label = 'BY'; |
||||
break; |
||||
case 'Berlin': |
||||
label = 'BE'; |
||||
break; |
||||
case 'Brandenburg': |
||||
label = 'BB'; |
||||
break; |
||||
case 'Bremen': |
||||
label = 'HB'; |
||||
break; |
||||
case 'Hamburg': |
||||
label = 'HB'; |
||||
break; |
||||
case 'Hessen': |
||||
label = 'HE'; |
||||
break; |
||||
case 'Mecklenburg-Vorpommern': |
||||
label = 'MV'; |
||||
break; |
||||
case 'Saarland': |
||||
label = 'SL'; |
||||
break; |
||||
case 'Sachsen': |
||||
label = 'SN'; |
||||
break; |
||||
case 'Sachsen-Anhalt': |
||||
label = 'SA'; |
||||
break; |
||||
case 'Schleswig-Holstein': |
||||
label = 'SH'; |
||||
break; |
||||
case 'Thüringen': |
||||
label = 'SN'; |
||||
break; |
||||
default: |
||||
label = this.props.state; |
||||
} |
||||
|
||||
return <abbr title={this.props.state}>{label}</abbr>; |
||||
} |
||||
} |
||||
|
||||
class TypeField extends Component { |
||||
render() { |
||||
var label = ''; |
||||
var title = ''; |
||||
|
||||
if (this.props.level === 'DE:BUNDESVERBAND') { |
||||
if (this.props.type === 'YOUTH_ORGANIZATION') { |
||||
title = 'Grüne Jugend Bundesverband'; |
||||
label = 'GJ BV'; |
||||
} else { |
||||
title = 'Bundesverband'; |
||||
label = 'BV'; |
||||
} |
||||
} else if (this.props.level === 'DE:LANDESVERBAND') { |
||||
if (this.props.type === 'YOUTH_ORGANIZATION') { |
||||
title = 'Grüne Jugend Landesverband'; |
||||
label = 'GJ LV'; |
||||
} else { |
||||
title = 'Landesverband'; |
||||
label = 'LV'; |
||||
} |
||||
} else if (this.props.level === 'DE:REGIONALVERBAND') { |
||||
title = 'Regionalverband'; |
||||
label = 'RV'; |
||||
} else if (this.props.level === 'DE:BEZIRKSVERBAND') { |
||||
title = 'Bezirksverband'; |
||||
label = 'BeV'; |
||||
} else if (this.props.level === 'DE:KREISVERBAND') { |
||||
if (this.props.type === 'YOUTH_ORGANIZATION') { |
||||
title = 'Grüne Jugend Kreisverband'; |
||||
label = 'GJ KV'; |
||||
} else { |
||||
title = 'Kreisverband'; |
||||
label = 'KV'; |
||||
} |
||||
} else if (this.props.level === 'DE:ORTSVERBAND') { |
||||
title = 'Ortsverband'; |
||||
label = 'OV'; |
||||
} |
||||
|
||||
return <abbr className='TypeField' title={title}>{label}</abbr>; |
||||
} |
||||
} |
||||
|
||||
class URLField extends Component { |
||||
displayURL(url) { |
||||
var match = url.match(/:\/\/(www[0-9]?\.)?(.[^/:]+)/i); |
||||
if (match != null && match.length > 2 && typeof match[2] === 'string' && match[2].length > 0) { |
||||
return match[2]; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
// truncation for too long URLs
|
||||
trunc(s, length) { |
||||
if (s.length > length) { |
||||
s = s.substring(0, length) + '…'; |
||||
} |
||||
return s; |
||||
} |
||||
|
||||
render() { |
||||
var labelURL = this.trunc(this.displayURL(punycode.toUnicode(this.props.inputURL)), 40); |
||||
return <span className='URLField'>{ labelURL }</span>; |
||||
} |
||||
} |
||||
|
||||
class LocationLabel extends Component { |
||||
render() { |
||||
var label = ""; |
||||
var type = <TypeField level={this.props.level} type={this.props.type} />; |
||||
|
||||
if (this.props.city === null && this.props.district !== null) { |
||||
label = this.props.district; |
||||
return <span className='LocationLabel'>{type} {label}, <StateField state={this.props.state} /></span>; |
||||
} else if (this.props.city !== null && this.props.district === null) { |
||||
label = this.props.city; |
||||
return <span className='LocationLabel'>{type} {label}, <StateField state={this.props.state} /></span>; |
||||
} else if (this.props.city !== null && this.props.district !== null) { |
||||
label = `${this.props.city}, ${this.props.district}`; |
||||
return <span className='LocationLabel'>{type} {label}, <StateField state={this.props.state} /></span>; |
||||
} |
||||
|
||||
label = this.props.state; |
||||
return <span className='LocationLabel'>{type} {label}</span>; |
||||
} |
||||
} |
||||
|
||||
|
||||
class ResultsList extends Component { |
||||
render() { |
||||
// sort results by score (descending)
|
||||
this.props.results.sort((a, b) => { |
||||
return b.score - a.score; |
||||
}); |
||||
|
||||
var rows = []; |
||||
this.props.results.forEach((element, index) => { |
||||
|
||||
var row = ( |
||||
<div className='ResultsList row' key={element.input_url}> |
||||
<div className='col-12'> |
||||
<Link to={`/sites/${ encodeURIComponent(element.input_url) }`}> |
||||
<div className='row'> |
||||
<div className='col-9'> |
||||
<LocationLabel level={element.meta.level} type={element.meta.type} district={element.meta.district} city={element.meta.city} state={element.meta.state} /> |
||||
</div> |
||||
<div className='col-3'> |
||||
<ScoreField score={element.score} maxScore={13} /> |
||||
</div> |
||||
</div> |
||||
<URLField key={'uf'+index} inputURL={element.input_url} canonicalURLs={element.resulting_urls} /> |
||||
</Link> |
||||
</div> |
||||
</div> |
||||
); |
||||
|
||||
rows.push(row); |
||||
}); |
||||
|
||||
return rows; |
||||
} |
||||
} |
||||
|
||||
export default ResultsList; |
@ -1,14 +0,0 @@ |
||||
.ResultsTable { |
||||
text-align: center; |
||||
font-size: 0.8rem; |
||||
} |
||||
|
||||
.ResultsTable td.text { |
||||
font-size: 0.8rem; |
||||
} |
||||
|
||||
.ResultsTable a.screenshot { |
||||
display: inline-block; |
||||
margin-left: 3px; |
||||
margin-right: 3px; |
||||
} |
@ -1,210 +0,0 @@ |
||||
/** |
||||
* The ResultsTable component is a table of results for all websites we checked. |
||||
*/ |
||||
|
||||
import React, { Component } from 'react'; |
||||
import { Link } from "react-router-dom"; |
||||
import './ResultsTable.css'; |
||||
import punycode from 'punycode'; |
||||
|
||||
|
||||
class CityField extends Component { |
||||
render() { |
||||
return <td key='city'>{ this.props.city }</td>; |
||||
} |
||||
} |
||||
|
||||
class DistrictField extends Component { |
||||
render() { |
||||
return <td key='district'>{ this.props.district }</td>; |
||||
} |
||||
} |
||||
|
||||
class ScoreField extends Component { |
||||
render() { |
||||
return <td key='score'>{ this.props.score }</td>; |
||||
} |
||||
} |
||||
|
||||
class StateField extends Component { |
||||
render() { |
||||
var label = this.props.state; |
||||
|
||||
switch (this.props.state) { |
||||
case 'Nordrhein-Westfalen': |
||||
label = 'NW'; |
||||
break; |
||||
case 'Rheinland-Pfalz': |
||||
label = 'RP'; |
||||
break; |
||||
case 'Niedersachsen': |
||||
label = 'NS'; |
||||
break; |
||||
case 'Baden-Württemberg': |
||||
label = 'BW'; |
||||
break; |
||||
case 'Bayern': |
||||
label = 'BY'; |
||||
break; |
||||
case 'Berlin': |
||||
label = 'BE'; |
||||
break; |
||||
case 'Brandenburg': |
||||
label = 'BB'; |
||||
break; |
||||
case 'Bremen': |
||||
label = 'HB'; |
||||
break; |
||||
case 'Hamburg': |
||||
label = 'HB'; |
||||
break; |
||||
case 'Hessen': |
||||
label = 'HE'; |
||||
break; |
||||
case 'Mecklenburg-Vorpommern': |
||||
label = 'MV'; |
||||
break; |
||||
case 'Saarland': |
||||
label = 'SL'; |
||||
break; |
||||
case 'Sachsen': |
||||
label = 'SN'; |
||||
break; |
||||
case 'Sachsen-Anhalt': |
||||
label = 'SA'; |
||||
break; |
||||
case 'Schleswig-Holstein': |
||||
label = 'SH'; |
||||
break; |
||||
case 'Thüringen': |
||||
label = 'SN'; |
||||
break; |
||||
default: |
||||
label = this.props.state; |
||||
} |
||||
|
||||
return <td key='state'><abbr title={this.props.state}>{label}</abbr></td>; |
||||
} |
||||
} |
||||
|
||||
class TypeField extends Component { |
||||
render() { |
||||
var label; |
||||
if (this.props.level === 'DE:BUNDESVERBAND') { |
||||
if (this.props.type === 'YOUTH_ORGANIZATION') { |
||||
label = <abbr title='Grüne Jugend Bundesverband'>GJ BV</abbr>; |
||||
} else { |
||||
label = <abbr title='Bundesverband'>BV</abbr>; |
||||
} |
||||
} else if (this.props.level === 'DE:LANDESVERBAND') { |
||||
if (this.props.type === 'YOUTH_ORGANIZATION') { |
||||
label = <abbr title='Grüne Jugend Landesverband'>GJ LV</abbr>; |
||||
} else { |
||||
label = <abbr title='Landesverband'>LV</abbr>; |
||||
} |
||||
} else if (this.props.level === 'DE:REGIONALVERBAND') { |
||||
label = <abbr title='Regionalverband'>RV</abbr>; |
||||
} else if (this.props.level === 'DE:BEZIRKSVERBAND') { |
||||
label = <abbr title='Bezirksverband'>BeV</abbr>; |
||||
} else if (this.props.level === 'DE:KREISVERBAND') { |
||||
if (this.props.type === 'YOUTH_ORGANIZATION') { |
||||
label = <abbr title='Grüne Jugend Kreisverband'>GJ KV</abbr>; |
||||
} else { |
||||
label = <abbr title='Kreisverband'>KV</abbr>; |
||||
} |
||||
} else if (this.props.level === 'DE:ORTSVERBAND') { |
||||
label = <abbr title='Ortsverband'>OV</abbr>; |
||||
} |
||||
return <td key='typefield'>{ label }</td>; |
||||
} |
||||
} |
||||
|
||||
class URLField extends Component { |
||||
|
||||
// truncation for too long URLs
|
||||
trunc(s, length) { |
||||
if (s.length > length) { |
||||
s = s.substring(0, length) + '…'; |
||||
} |
||||
return s; |
||||
} |
||||
|
||||
render() { |
||||
var inputDisplayURL = this.trunc(punycode.toUnicode(this.props.inputURL), 45); |
||||
|
||||
// There is a canonical URL...
|
||||
if (typeof this.props.canonicalURLs !== 'undefined' && this.props.canonicalURLs !== null && this.props.canonicalURLs.length === 1) { |
||||
|
||||
// and it is the same as the input URL
|
||||
if (this.props.inputURL === this.props.canonicalURLs[0]) { |
||||
return <td key='url'>→ <a href={this.props.inputURL} target="_blank" rel='noopener noreferrer'> { inputDisplayURL }</a></td>; |
||||
} |
||||
|
||||
// canonical URL contains input URL (as prefix)
|
||||
if (this.props.canonicalURLs[0].indexOf(this.props.inputURL) === 0) { |
||||
var targetLabel = '/' + this.props.canonicalURLs[0].substr(this.props.inputURL.length); |
||||
return <td key='url'><a href={this.props.inputURL} target="_blank" rel='noopener noreferrer'> { inputDisplayURL }</a> → <a href={this.props.canonicalURLs[0]} rel='noopener noreferrer'>{targetLabel}</a></td>; |
||||
} |
||||
|
||||
var targetDisplayURL = this.trunc(punycode.toUnicode(this.props.canonicalURLs[0]), 45); |
||||
return ( |
||||
<td key='url'> |
||||
<a href={this.props.inputURL} target="_blank" rel='noopener noreferrer'> { inputDisplayURL }</a><br /> |
||||
→ <a href={this.props.canonicalURLs[0]} target="_blank" rel='noopener noreferrer'> { targetDisplayURL }</a> |
||||
</td> |
||||
); |
||||
} |
||||
|
||||
// no canonical URL
|
||||
return <td key='url'><a href={this.props.inputURL} target="_blank" rel='noopener noreferrer'> { inputDisplayURL }</a></td>; |
||||
} |
||||
} |
||||
|
||||
|
||||
class ResultsTable extends Component { |
||||
render() { |
||||
// sort results by score (descending)
|
||||
this.props.results.sort((a, b) => { |
||||
return b.score - a.score; |
||||
}); |
||||
|
||||
var rows = []; |
||||
this.props.results.forEach((element, index) => { |
||||
|
||||
var fields = [ |
||||
<TypeField key={'tf'+index} level={element.meta.level} type={element.meta.type} />, |
||||
<StateField key={'sf'+index} state={element.meta.state} />, |
||||
<DistrictField key={'df'+index} district={element.meta.district} />, |
||||
<CityField key={'cf'+index} city={element.meta.city} />, |
||||
<URLField key={'uf'+index} inputURL={element.input_url} canonicalURLs={element.resulting_urls} />, |
||||
<ScoreField key={'scf'+index} score={element.score} />, |
||||
( |
||||
<td key={'link-'+index}> |
||||
<Link to={`/sites/${ encodeURIComponent(element.input_url) }`}>Details</Link> |
||||
</td> |
||||
), |
||||
]; |
||||
|
||||
rows.push(<tr key={element.input_url}>{ fields }</tr>) |
||||
}); |
||||
|
||||
return ( |
||||
<table className='table ResultsTable'> |
||||
<thead> |
||||
<tr> |
||||
<th scope='col'>Typ</th> |
||||
<th scope='col'>Land</th> |
||||
<th scope='col'>Kreis</th> |
||||
<th scope='col'>Stadt</th> |
||||
<th scope='col'>URL</th> |
||||
<th scope='col'>Score</th> |
||||
<th scope='col'>Link</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody>{ rows }</tbody> |
||||
</table> |
||||
); |
||||
} |
||||
} |
||||
|
||||
export default ResultsTable; |
Loading…
Reference in new issue