summaryrefslogtreecommitdiff
path: root/scraper/client/common
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2019-02-13 13:58:11 +0100
committerJules Laplace <julescarbon@gmail.com>2019-02-13 13:58:11 +0100
commit392ea8d0ba2fdc713ae156517b0575e8219b9f1c (patch)
treebb29c19f9f0a2d970c39c813130361405fccbe4e /scraper/client/common
parentdc7d9cbba842472efb33186e97ee55751e4d50ca (diff)
adding geocode client
Diffstat (limited to 'scraper/client/common')
-rw-r--r--scraper/client/common/activeLink.component.js16
-rw-r--r--scraper/client/common/common.css347
-rw-r--r--scraper/client/common/footer.component.js10
-rw-r--r--scraper/client/common/gate.component.js21
-rw-r--r--scraper/client/common/header.component.js19
-rw-r--r--scraper/client/common/index.js22
-rw-r--r--scraper/client/common/loader.component.js10
-rw-r--r--scraper/client/common/sidebar.component.js25
-rw-r--r--scraper/client/common/table.component.js121
9 files changed, 591 insertions, 0 deletions
diff --git a/scraper/client/common/activeLink.component.js b/scraper/client/common/activeLink.component.js
new file mode 100644
index 00000000..59f63881
--- /dev/null
+++ b/scraper/client/common/activeLink.component.js
@@ -0,0 +1,16 @@
+import React from 'react'
+import { NavLink } from 'react-router-dom'
+
+export default function ActiveLink({
+ to,
+ className = 'navlink',
+ children
+}) {
+ return (
+ <span className={className}>
+ <NavLink to={to}>
+ {children}
+ </NavLink>
+ </span>
+ )
+}
diff --git a/scraper/client/common/common.css b/scraper/client/common/common.css
new file mode 100644
index 00000000..4b939df0
--- /dev/null
+++ b/scraper/client/common/common.css
@@ -0,0 +1,347 @@
+/* css boilerplate */
+
+* { box-sizing: border-box; }
+html,body {
+ margin: 0; padding: 0;
+ width: 100%; height: 100%;
+}
+body {
+ font-family: Helvetica, sans-serif;
+ font-weight: 300;
+}
+
+h1 {
+
+}
+h2 {
+ font-weight: normal;
+ margin: 10px 0;
+ padding: 3px;
+ font-size: 24px;
+}
+h3 {
+ font-weight: normal;
+ margin: 10px 0 0 0;
+ padding: 3px;
+ font-size: 18px;
+}
+h4 {
+ font-weight: 300;
+ font-size: 12px;
+ letter-spacing: 2px;
+ color: #888;
+ text-transform: uppercase;
+ margin: 5px 10px;
+ margin-top: 20px;
+}
+h4:first-child {
+ margin-top: 10px;
+}
+
+.app {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ justify-content: flex-start;
+}
+
+/* header stuff */
+
+header {
+ width: 100%;
+ background: #11f;
+ color: white;
+ align-items: stretch;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ z-index: 3;
+}
+header > section {
+ justify-content: flex-start;
+ align-items: center;
+ display: flex;
+ flex: 1 0;
+ font-weight: bold;
+}
+header > section:last-of-type {
+ justify-content: flex-end;
+}
+
+/* sidebar / body columns */
+
+.sidebar {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: flex-start;
+ height: 100%;
+ float: left;
+ width: 200px;
+ flex: 0 0 200px;
+ padding: 10px;
+ margin-right: 10px;
+}
+.sidebar a {
+ display: block;
+ padding: 10px 10px;
+ text-decoration: none;
+ color: #444;
+}
+.sidebar a.active {
+ font-weight: bold;
+ color: #222;
+}
+.body {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: flex-start;
+ flex-grow: 1;
+}
+.body > div {
+ padding-bottom: 40px;
+}
+
+/* buttons / forms */
+
+.btn:focus, .btn:hover {
+ background: #f1f1fc;
+ color: #4b48d6 !important;
+ text-decoration: none;
+}
+.btn {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ background: #fff;
+ border: .05rem solid;
+ border-radius: 2px;
+ margin-right: 5px;
+ color: #11f;
+ cursor: pointer;
+ display: inline-block;
+ font-size: .8rem;
+ height: 1.8rem;
+ line-height: 1rem;
+ outline: none;
+ padding: .35rem .4rem;
+ text-align: center;
+ text-decoration: none;
+ -webkit-transition: all .2s ease;
+ -o-transition: all .2s ease;
+ transition: all .2s ease;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ vertical-align: middle;
+ white-space: nowrap;
+}
+.btn.reset,
+.btn.panic {
+ color: #b00;
+}
+.btn.btn-primary {
+ background: #11f;
+ border-color: #11f;
+ color: white;
+}
+.btn[disabled] {
+ color: #bbb !important;
+ border-color: #bbb !important;
+ background: white !important;
+ cursor: default;
+}
+.btn.btn-primary:focus,
+.btn.btn-primary:hover {
+ background: #0808ee;
+ color: white !important;
+}
+.row .btn {
+ margin: 0 5px 0 0;
+}
+input[type=text] {
+ border: 1px solid #888;
+ padding: 4px;
+ font-size: 15px;
+}
+
+
+/* tables on metadata pages */
+
+table {
+ border: 0;
+ margin: 0;
+ padding: 0;
+ border-spacing: 0;
+}
+.tableObject td,
+.tableObject th {
+ padding: 3px;
+ vertical-align: top;
+}
+.tableObject hr {
+ width: 100%;
+ color: transparent;
+ border: 0;
+ border-bottom: 1px solid #bbb;
+ align: left;
+ margin: 3px 0;
+ padding: 0;
+}
+.tableObject th,
+.tableTuples th {
+ min-width: 145px;
+ text-align: left;
+ text-transform: capitalize;
+ padding: 3px;
+ padding-right: 10px;
+ font-weight: 300;
+ color: #333;
+}
+.tableTuples td {
+ text-align: right;
+ padding: 3px;
+}
+.tableObject td {
+ font-weight: normal;
+ color: #000;
+}
+.tableObject .tableObject {
+ border: 1px solid #ddd;
+}
+.tableArray {
+ border: 1px solid #ddd;
+ border-spacing: 0;
+}
+.tableArray td {
+ border-bottom: 1px solid #ddd;
+}
+.gray {
+ font-size: 12px;
+ color: #888;
+ display: block;
+}
+.sha256.heading {
+ margin: 20px 0 0px;
+}
+.gray span {
+ padding-right: 5px;
+}
+.gray {
+ margin-bottom: 10px;
+}
+.gray a {
+ color: #666;
+}
+
+.verified {
+ color: #080;
+ font-weight: bold;
+}
+.unverified {
+ color: #f00;
+ font-weight: 300;
+}
+
+.loading, .error {
+ font-weight: normal;
+ margin: 10px 0;
+ padding: 3px;
+ font-size: 24px;
+}
+
+.title {
+ text-transform: capitalize;
+}
+.rect {
+ position: absolute;
+}
+.rect { border: 1px solid rgba(0,0,255); background-color: rgba(0,0,255,0.1); }
+
+/* videos / video preloader */
+
+video {
+ max-width: 640px;
+ margin: 10px 0;
+}
+.video {
+ margin: 0 0 10px 0;
+}
+.video .bg {
+ cursor: pointer;
+ position: relative;
+ background-size: cover;
+}
+.video .play {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate3d(-50%, -50%, 0);
+ width: 20%;
+ height: 20%;
+ background-image: url(/search/static/img/play.png);
+ background-position: center center;
+ background-size: contain;
+ background-repeat: no-repeat;
+}
+.desktop .video .play:hover {
+ -webkit-filter: invert(60%) sepia(100%) saturate(500%) hue-rotate(160deg);
+}
+
+/* spectre.css loader */
+
+.loaderWrapper {
+ display: inline-block;
+ position: relative;
+ width: .8rem;
+ height: .8rem;
+ padding: 10px;
+}
+.loader {
+ color: transparent !important;
+ min-height: .8rem;
+ pointer-events: none;
+ position: relative;
+}
+
+.loader::after {
+ animation: loader 500ms infinite linear;
+ border: .1rem solid #5755d9;
+ border-radius: 50%;
+ border-right-color: transparent;
+ border-top-color: transparent;
+ content: "";
+ display: block;
+ height: .8rem;
+ left: 50%;
+ margin-left: -.4rem;
+ margin-top: -.4rem;
+ position: absolute;
+ top: 50%;
+ width: .8rem;
+ z-index: 1;
+}
+
+.loader.loader-lg {
+ min-height: 2rem;
+}
+
+.loader.loader-lg::after {
+ height: 1.6rem;
+ margin-left: -.8rem;
+ margin-top: -.8rem;
+ width: 1.6rem;
+}
+
+@keyframes loader {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+} \ No newline at end of file
diff --git a/scraper/client/common/footer.component.js b/scraper/client/common/footer.component.js
new file mode 100644
index 00000000..7c82b44b
--- /dev/null
+++ b/scraper/client/common/footer.component.js
@@ -0,0 +1,10 @@
+import React from 'react'
+import { Link } from 'react-router-dom'
+import { connect } from 'react-redux'
+
+export default function Footer(props) {
+ return (
+ <footer>
+ </footer>
+ );
+}
diff --git a/scraper/client/common/gate.component.js b/scraper/client/common/gate.component.js
new file mode 100644
index 00000000..9bf9287b
--- /dev/null
+++ b/scraper/client/common/gate.component.js
@@ -0,0 +1,21 @@
+import React from 'react'
+import { connect } from 'react-redux'
+
+function Gate(props) {
+ const { app, tag, View } = props
+ const data = app[tag]
+ if (!data) return null
+ if (data === 'loading') {
+ return <div className='tableObject loading'>{tag}{': Loading'}</div>
+ }
+ if (data.err) {
+ return <div className='tableObject error'>{tag}{' Error: '}{data.err}</div>
+ }
+ return <View data={data} {...props} />
+}
+
+const mapStateToProps = state => ({
+ app: state.metadata
+})
+
+export default connect(mapStateToProps)(Gate)
diff --git a/scraper/client/common/header.component.js b/scraper/client/common/header.component.js
new file mode 100644
index 00000000..650df5fc
--- /dev/null
+++ b/scraper/client/common/header.component.js
@@ -0,0 +1,19 @@
+import React, { Component } from 'react'
+import { NavLink } from 'react-router-dom'
+import { connect } from 'react-redux'
+
+class Header extends Component {
+ componentDidMount(){
+
+ }
+ render() {
+ return (
+ )
+ }
+}
+
+const mapStateToProps = state => ({
+ // hash: state.metadata.hash,
+})
+
+export default connect(mapStateToProps)(Sidebar)
diff --git a/scraper/client/common/index.js b/scraper/client/common/index.js
new file mode 100644
index 00000000..7f4d9870
--- /dev/null
+++ b/scraper/client/common/index.js
@@ -0,0 +1,22 @@
+import ActiveLink from './activeLink.component'
+import Header from './header.component'
+import Footer from './footer.component'
+import Loader from './loader.component'
+import Sidebar from './sidebar.component'
+import Gate from './gate.component'
+import { TableObject, TableArray, TableTuples, TableRow, TableCell } from './table.component'
+import './common.css'
+
+export {
+ Header,
+ Footer,
+ Sidebar,
+ Loader,
+ Gate,
+ TableObject,
+ TableArray,
+ TableTuples,
+ TableRow,
+ TableCell,
+ ActiveLink,
+}
diff --git a/scraper/client/common/loader.component.js b/scraper/client/common/loader.component.js
new file mode 100644
index 00000000..6795424b
--- /dev/null
+++ b/scraper/client/common/loader.component.js
@@ -0,0 +1,10 @@
+import React, { Component } from 'react'
+
+export default function Loader() {
+ return (
+ <div className='loaderWrapper'>
+ <div className='loader'>
+ </div>
+ </div>
+ )
+} \ No newline at end of file
diff --git a/scraper/client/common/sidebar.component.js b/scraper/client/common/sidebar.component.js
new file mode 100644
index 00000000..f0dbe750
--- /dev/null
+++ b/scraper/client/common/sidebar.component.js
@@ -0,0 +1,25 @@
+import React, { Component } from 'react'
+import { NavLink } from 'react-router-dom'
+import { connect } from 'react-redux'
+
+class Sidebar extends Component {
+ render() {
+ const { hash } = this.props
+ if (!hash) {
+ return (
+ <div className="sidebar">
+ </div>
+ )
+ }
+ return (
+ <div className="sidebar">
+ </div>
+ )
+ }
+}
+
+const mapStateToProps = state => ({
+ hash: state.metadata.hash,
+})
+
+export default connect(mapStateToProps)(Sidebar)
diff --git a/scraper/client/common/table.component.js b/scraper/client/common/table.component.js
new file mode 100644
index 00000000..76a1d57c
--- /dev/null
+++ b/scraper/client/common/table.component.js
@@ -0,0 +1,121 @@
+import React from 'react'
+
+import { formatName } from '../util'
+
+const __HR__ = '__HR__'
+
+export function TableObject({ tag, object, order, summary }) {
+ if (!object) return null
+ if (object === 'loading') {
+ return <div className='tableObject loading'>{tag}{': Loading'}</div>
+ }
+ if (object.err) {
+ return <div className='tableObject error'>{tag}{' Error: '}{object.err}</div>
+ }
+ let objects = Object.keys(object)
+ if (order) {
+ const grouped = objects.reduce((a, b) => {
+ const index = order.indexOf(b)
+ if (index !== -1) {
+ a.order.push([index, b])
+ } else {
+ a.alpha.push(b)
+ }
+ return a
+ }, { order: [], alpha: [] })
+ objects = grouped.order
+ .sort((a, b) => a[0] - b[0])
+ .map(([i, s]) => s)
+ if (!summary) {
+ objects = objects
+ // .concat([__HR__])
+ .concat(grouped.alpha.sort())
+ }
+ } else {
+ objects = objects.sort()
+ }
+ return (
+ <div>
+ {tag && <h3>{tag}</h3>}
+ <table className={'tableObject ' + tag}>
+ <tbody>
+ {objects.map((key, i) => (
+ <TableRow key={key + '_' + i} name={key} value={object[key]} />
+ ))}
+ </tbody>
+ </table>
+ </div>
+ )
+}
+
+export function TableArray({ tag, list }) {
+ if (!list) return null
+ return (
+ <div>
+ {tag && <h3>{tag}</h3>}
+ <table className={'tableArray ' + tag}>
+ <tbody>
+ {list.map((value, i) => (
+ <tr key={tag + '_' + i}>
+ <TableCell value={value} />
+ </tr>
+ ))}
+ </tbody>
+ </table>
+ </div>
+ )
+}
+
+export function TableTuples({ tag, list }) {
+ if (!list) return null
+ return (
+ <div>
+ {tag && <h3>{tag}</h3>}
+ <table className={'tableTuples ' + tag}>
+ <tbody>
+ {list.map(([key, ...values], i) => (
+ <tr key={tag + '_' + i}>
+ <th>{formatName(key)}</th>
+ {values.map((value, j) => (
+ <TableCell key={i + '_' + j} value={value} />
+ ))}
+ </tr>
+ ))}
+ </tbody>
+ </table>
+ </div>
+ )
+}
+
+export function TableRow({ name, value }) {
+ if (name === __HR__) {
+ return (
+ <tr>
+ <th className='tr'>
+ <hr />
+ </th>
+ </tr>
+ )
+ }
+ return (
+ <tr>
+ <th>{formatName(name)}</th>
+ <TableCell name={name} value={value} />
+ </tr>
+ )
+}
+
+export function TableCell({ value }) {
+ if (value && typeof value === 'object') {
+ if (value._raw) {
+ value = value.value
+ } else if (value.length) {
+ value = <TableArray nested tag={''} list={value} />
+ } else {
+ value = <TableObject nested tag={''} object={value} />
+ }
+ }
+ return (
+ <td>{value}</td>
+ )
+}