This commit is contained in:
Mihajlo Medjedovic
2024-06-05 15:53:46 +02:00
commit fd510b88c4
270 changed files with 27578 additions and 0 deletions

23
src/pages/404.tsx Normal file
View File

@@ -0,0 +1,23 @@
import React from 'react'
// import { Link } from 'gatsby'
import Layout from '../components/layout'
import Seo from '../components/seo'
import { Section } from '../components/shared'
import { SideBar } from '../templates/sidebar'
const NotFound = ({ data, location, pageContext }) => (
<Layout location={location} heroSection={false}>
<Seo title="Page Not Found" />
<Section color="black" bgColor="white" bottomArrow={false}>
<SideBar
pageContext={pageContext}
location={location}
notFoundPage={true}
/>
</Section>
</Layout>
)
export default NotFound

215
src/pages/about.tsx Normal file
View File

@@ -0,0 +1,215 @@
import { PageProps, Link, graphql } from 'gatsby'
import React from 'react'
import Layout from '../components/layout'
import Seo from '../components/seo'
import { Section } from '../components/shared'
import {
SectionHeading,
SectionDesc
} from '../components/shared/styledComponents'
import {
Card,
CardImg,
CardBody,
FeaturedImg,
FeaturedDesc
} from '../styledComponents/about'
import sasenseiLogo from '../images/sasapps/sasensei.png'
import rubyLogo from '../images/sasapps/ruby.png'
import pygrailLogo from '../images/sasapps/pygrail.png'
import pilotLogo from '../images/sasapps/pilot.png'
import yogaLogo from '../images/sasapps/yoga.png'
import jsLogo from '../images/sasapps/js.png'
import serbianLogo from '../images/sasapps/serbian.png'
import quizrLogo from '../images/sasapps/quizr.png'
import cdoquizLogo from '../images/sasapps/cdoquiz.png'
import insureLogo from '../images/sasapps/insure.png'
import sasenseiFeatured from '../images/sasensei_featured.png'
type DataProps = {
site: {
meta: {
title: string
description: string
social: { linkedin: string }
}
}
}
const SasApps = [
{
name: 'Sasensei',
desc: 'Sasensei. SAS Software Quiz, Challenge, Compete & Learn',
link: 'https://sasensei.com',
themeColor: '#2196F3',
logo: sasenseiLogo
},
{
name: 'Ruby',
desc: 'Ruby Cards - a Community Quiz Game for Rubyists',
link: 'https://ruby.cards',
themeColor: '#aa1502',
logo: rubyLogo
},
{
name: 'PyGrail',
desc: 'PyGrail - a Community Quiz Game for Monty Pythonistas',
link: 'https://pygrail.com',
themeColor: '#efbf2c',
logo: pygrailLogo
},
{
name: 'Pilot',
desc: 'Pilot Cards Leaderboard - How High Can You Climb?',
link: 'https://pilot.cards',
themeColor: '#446ff3',
logo: pilotLogo
},
{
name: 'Yoga.cards',
desc: 'Yoga Cards - a Community Quiz Game for Student Yogis',
link: 'https://yoga.cards',
themeColor: '#6d69fb',
logo: yogaLogo
},
{
name: 'JS.cards',
desc: 'JS Cards - a Community Quiz Game for JavaScript Ninjas',
link: 'https://js.cards',
themeColor: '#00cc99',
logo: jsLogo
},
{
name: 'Serbian.cards',
desc: 'Serbian Cards - How Much Serbian Do You Know?',
link: 'https://serbian.cards',
themeColor: '#c6363c',
logo: serbianLogo
},
{
name: 'Quizr',
desc: 'quizR - a community quiz game for useRs',
link: 'https://quizr.io',
themeColor: '#51904c',
logo: quizrLogo
},
{
name: 'CDOquiz',
desc: 'CDO Quiz - a Royally Challenging Data Adventure',
link: 'https://cdoquiz.com/',
themeColor: '#a54499',
logo: cdoquizLogo
},
{
name: 'Insure.cards',
desc: 'Insure Cards - Are You An Insurance Expert? Prove It',
link: 'https://insure.cards/',
themeColor: '#5f8ba5',
logo: insureLogo
}
]
const About: React.FC<PageProps<DataProps>> = ({ data, location }) => {
return (
<Layout
location={location}
heading="Behind Data Controller"
desc="Data Controller is a product of 4GL, a brand of Bowe IO Ltd"
>
<Seo title="About" />
<Section color="black" bgColor="white">
<div className="row">
<div className="offset-md-2 col-md-8">
<SectionHeading center="no">About Data Controller</SectionHeading>
<SectionDesc center="no">
Data Controller is sold through Bowe IO Ltd, a company&nbsp;based
in the UK and operating since 2013.
<br />
The company supports the development of the Data Controller web
application and other{' '}
<a href="https://sasapps.io" title="SAS Apps">
SAS Apps
</a>
, and the Macro Cards range of websites listed below:
</SectionDesc>
</div>
</div>
<div className="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 row-cols-xl-5">
{SasApps.map((app) => (
<div className="col">
<Card
className="card"
href={app.link}
target="_blank"
rel="noopener"
>
<CardImg
className="card-img-top"
src={app.logo}
alt={app.name}
title={app.name}
/>
<CardBody className="card-body">
<h5 className="card-title">{app.name}</h5>
<p className="card-text">{app.desc}</p>
</CardBody>
</Card>
</div>
))}
</div>
</Section>
<Section>
<FeaturedImg src={sasenseiFeatured} alt="Sasensei" title="Sasensei" />
<FeaturedDesc>
Sasensei is a free question-based learning system dedicated to various
aspects of the
<br />
SAS® software such as SAS® Programming, Administration, Risk
Dimensions, Viya, AF/SCL, and much more.
</FeaturedDesc>
<FeaturedDesc>
This SAS® quiz allows the player to test their knowledge, challenge
their peers and submit their own questions for others to enjoy.
<br />
Sasensei is constantly improving by adding new features which
contribute to the player experience and increase the educational
value.
</FeaturedDesc>
</Section>
<Section color="black" bgColor="#eaeaea" bottomArrow={false}>
<div className="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 row-cols-xl-5">
<div className="col">
1000+
<br />
Active Players
</div>
<div className="col">
650+
<br />
Questions
</div>
<div className="col">
20+
<br />
New Players Every Day
</div>
<div className="col">
6<br />
Unique Features
</div>
<div className="col">
7<br />
Difficulty Levels
</div>
</div>
</Section>
</Layout>
)
}
export default About

124
src/pages/contact.tsx Normal file
View File

@@ -0,0 +1,124 @@
import { PageProps, Link, graphql } from 'gatsby'
import React from 'react'
import Layout from '../components/layout'
import Seo from '../components/seo'
import { Section } from '../components/shared'
import {
SectionHeading,
SectionDesc,
SolidButton
} from '../components/shared/styledComponents'
import {
StyledHeading,
StyledLabel,
ContactBackground
} from '../styledComponents/contact'
import contactBg from '../images/contact_bg.jpg'
import '../styledComponents/contact.css'
type DataProps = {
site: {
meta: {
title: string
description: string
social: { linkedin: string }
}
}
}
const Contact: React.FC<PageProps<DataProps>> = ({ data, location }) => {
return (
<Layout
location={location}
heading="Book a Demo"
desc="Schedule a demonstration of the Data Controller to see our latest features and explore use cases"
>
<Seo title="Contact" />
<Section color="black" bgColor="white" bottomArrow={false}>
<div className="row">
<div className="col-md-6">
<SectionHeading center="no">Schedule a Call</SectionHeading>
<SectionDesc center="no">
Feel free to contact us at any time to book a demo and start your
Data Controller journey. Our team will respond within 24 hours and
help you proceed with the registration process.
</SectionDesc>
<StyledHeading>Contact Us</StyledHeading>
<form
className="kwes-form"
method="POST"
action="https://kwes.io/api/foreign/forms/mxKuyK4lxZWnG2WNH3ga"
>
<div className="mb-3">
<StyledLabel htmlFor="name" className="form-label">
Name
</StyledLabel>
<input
type="text"
className="form-control contactFormStyles"
id="name"
name="name"
rules="required|max:50"
/>
</div>
<div className="mb-3">
<StyledLabel htmlFor="email" className="form-label">
Email address
</StyledLabel>
<input
type="email"
className="form-control contactFormStyles"
id="email"
name="email"
rules="required|email"
aria-describedby="emailHelp"
/>
<div id="emailHelp" className="form-text">
We'll never share your email with anyone else.
</div>
</div>
<div className="mb-3">
<StyledLabel htmlFor="subject" className="form-label">
Subject
</StyledLabel>
<input
type="text"
className="form-control contactFormStyles"
id="subject"
name="subject"
rules="required|max:50"
/>
</div>
<div className="mb-3">
<StyledLabel htmlFor="mesage" className="form-label">
Message
</StyledLabel>
<textarea
className="form-control contactFormStyles"
id="mesage"
name="message"
rows="5"
rules="required|max:200"
></textarea>
</div>
<div className="mb-3">
<SolidButton theme="dark">Submit</SolidButton>
</div>
</form>
</div>
<div className="col-md-6">
<ContactBackground src={contactBg} info="Book a Demo" />
</div>
</div>
</Section>
</Layout>
)
}
export default Contact

79
src/pages/faq.tsx Normal file
View File

@@ -0,0 +1,79 @@
import { PageProps, Link, graphql } from 'gatsby'
import React from 'react'
import Layout from '../components/layout'
import Seo from '../components/seo'
import { Section } from '../components/shared'
import {
SectionHeading,
SectionDesc,
SolidButton
} from '../components/shared/styledComponents'
import { FAQ } from '../styledComponents/faq'
type DataProps = {
site: {
meta: {
title: string
description: string
social: { linkedin: string }
}
}
}
const Faq: React.FC<PageProps<DataProps>> = ({ data, location }) => {
return (
<Layout
location={location}
heading="Data Controller FAQ"
desc="Most common user questions and answers regarding the Data Controller"
>
<Seo title="FAQ" />
<Section color="black" bgColor="white">
<div className="row">
<div className="col-md-8">
<FAQ
question="DOES THE DATA CONTROLLER ENABLE USERS TO CHANGE THE DATA MODEL (DATA STRUCTURE)?"
answer="A: No. This is not (and will not be) part of the feature set. Users can submit changes to data, but they cannot affect the number or type of columns in a table."
></FAQ>
<FAQ
question="Will this tool allow tables to be updated in my preferred database?"
answer="A: If you have a SAS connector (ACCESS engine) then the answer is likely yes. However, if your tables have database specific features (eg auto-generated keys) or non-standard column types (eg images or BLOBS) then the table may not be compatible. Please contact us for more information, as there are likely to be workarounds."
></FAQ>
<FAQ
question="Will this tool work on tables with Retained / Surrogate keys?"
answer="A: Yes, just define your business / natural key in the RK_UNDERLYING field of the configuration table."
></FAQ>
</div>
</div>
</Section>
<Section>
<div className="row">
<div className="offset-md-3 col-md-6">
<SectionDesc opacity="1">
For any further information regarding Data Controller please
reference our <Link to="/contact/">Contact page</Link> and send us
your questions. Our team will review it and follow up within 24
hours.
</SectionDesc>
</div>
</div>
</Section>
<Section color="black" bgColor="white" bottomArrow={false}>
<Link
to="/contact/"
className="d-flex justify-content-center"
style={{
textDecoration: 'none'
}}
>
<SolidButton theme="dark">Contact Us</SolidButton>
</Link>
</Section>
</Layout>
)
}
export default Faq

272
src/pages/index.tsx Normal file
View File

@@ -0,0 +1,272 @@
import { Link, graphql } from 'gatsby'
import React from 'react'
import Gallery from '@browniebroke/gatsby-image-gallery'
import { IGatsbyImageData } from 'gatsby-plugin-image'
import Layout from '../components/layout'
import Seo from '../components/seo'
import { Section, ScheduleDemo } from '../components/shared'
import {
SectionHeading,
SectionDesc
} from '../components/shared/styledComponents'
import {
Art,
Reason,
CenteredText,
Feature,
ThumbnailWrapper
} from '../styledComponents'
import leftArt from '../images/home_illustration2.png'
import rightArt from '../images/home_illustration1.png'
import dcSoftwareArt from '../images/dc-software.png'
import { AiOutlineClockCircle, AiFillLock } from 'react-icons/ai'
import { TiTick } from 'react-icons/ti'
import { HiOutlineRefresh } from 'react-icons/hi'
import { MdHistory } from 'react-icons/md'
import { BsCode } from 'react-icons/bs'
import { BiNetworkChart } from 'react-icons/bi'
import dcDesign from '../images/data-controller-design.png'
interface ImageSharpEdge {
node: {
childImageSharp: {
thumb: IGatsbyImageData
full: IGatsbyImageData
meta: {
originalName: string
}
}
}
}
interface PageProps {
data: {
images: {
edges: ImageSharpEdge[]
}
}
}
const Home: React.FC<PageProps> = ({ data, location }) => {
const images = data.images.edges.map(({ node }) => ({
...node.childImageSharp,
// Use original name as caption.
// The `originalName` is queried in a nested field,
// but the `Gallery` component expects `caption` at the top level.
caption: node.childImageSharp.meta.originalName
}))
return (
<Layout
location={location}
heading="Flexible and Secure Data Modification"
desc="Data Controller for SAS® enables business users to update IT owned source tables, secured by review / approve workflow and full audit trail."
>
<Seo />
<Section color="black" bgColor="white">
<div className="row">
<div className="col-md-3">
<Art src={leftArt} info="Business Owner" />
</div>
<div className="col-md-6">
<SectionHeading>Who is Data Controller for?</SectionHeading>
<SectionDesc>
Data Controller is designed to provide business users with a tool
which can be included in their overall armoury for regulatory
reporting.
</SectionDesc>
<SectionDesc>
Having worked in data-intensive SAS environments for many years,
the founders of Data Controller experienced first hand the
inefficient practices that reporting teams had to endure when
changes needed to be made to the data and source system access
wasnt possible.
</SectionDesc>
<SectionDesc>
It was clear to see that users needed the ability to self-serve
their data updates. That data owners should have the chance to
review and approve those updates. And that all changes to data
should be safe and secure, as well as tracked and visible for
audit reasons.
</SectionDesc>
<SectionDesc>
The Data Controller is useful for any Enterprise that needs to
perform manual data uploads into their preferred database, in
real-time, with full validation, approval, security, and control.
</SectionDesc>
</div>
<div className="col-md-3">
<Art src={rightArt} info="Clinical Research Data" />
</div>
</div>
</Section>
<Section color="black" bgColor="white">
<div className="row">
<div className="offset-md-2 col-md-8">
<SectionDesc>Devoted to</SectionDesc>
<SectionHeading>SAS® Users, Admins and Developers</SectionHeading>
<SectionDesc>
Most (if not all) SAS users have the basic need to load, modify or
delete data in SAS. They can typically achieve this by:
</SectionDesc>
</div>
</div>
<br />
<br />
<br />
<div className="row">
<div className="col-md-4">
<Reason text="Placing files on network drives ready for a batch program to load them" />
<Reason text="Updating data directly using SAS® code" />
<Reason text="Opening a dataset in Enterprise Guide and changing a value" />
<Reason text="Asking a DBA to run a script update" />
</div>
<div className="col-md-4">
<CenteredText>
The approaches mentioned are less than ideal for a number of
reasons:
</CenteredText>
<Art src={dcSoftwareArt} info="Data Controller Software" />
</div>
<div className="col-md-4">
<Reason
text="Every new piece of data requires a new job or program to be created to load it"
bgColor="red"
/>
<Reason
text="END USERS NEED TO BE GRANTED MODIFY ACCESS TO SENSITIVE DATA LOCATIONS"
bgColor="red"
/>
<Reason text="High risk of locking datasets" bgColor="red" />
<Reason
text="Need for change requests and delays to the process"
bgColor="red"
/>
</div>
</div>
<br />
<br />
<br />
<div className="row">
<div className="offset-md-2 col-md-8">
<SectionHeading>Data Controller Features</SectionHeading>
<SectionDesc>
Our goal with Data Controller is to focus on great user experience
and auditor satisfaction.
<br />
Our software saves years of development and testing, as well as
avoiding a black box custom build.
<br />
It is a SAS® Powered Web Application with the following features:
</SectionDesc>
</div>
</div>
<br />
<br />
<br />
<div className="row">
<Feature
title="Real-time"
desc="Intra day, concurrent updates are managed using a lock table and queuing mechanism. Updates are aborted if another user has changed the table since the approval diff was generated."
Icon={AiOutlineClockCircle}
className="col-sm-6 col-md-6 col-xl-4"
/>
<Feature
title="Secure"
desc="The existing SASLogon framework is used to manage Authentication &amp; Authorisation. End users do not require direct access to the target tables."
Icon={AiFillLock}
className="col-sm-6 col-md-6 col-xl-4"
/>
<Feature
title="Approval Mechanism"
desc="All data changes require 1 or more approvals before updating the table. The approver sees only the changes that will be applied to the target (new/deleted/changed rows)."
Icon={TiTick}
className="col-sm-6 col-md-6 col-xl-4"
/>
<Feature
title="Loading Tables of Different Types"
desc="Using SAS®&nbsp;libname engines, you can securely update tables in your preferred database. Data Controller supports Retained keys, SCD2 loads, Bitemporal, and composite primary keys."
Icon={HiOutlineRefresh}
className="col-sm-6 col-md-6 col-xl-3"
/>
<Feature
title="Full Audit History"
desc="You are able to track every change of data, including who made the change, when, why, and what the actual change was. You are able to access this feature on the History page."
Icon={MdHistory}
className="col-sm-6 col-md-4 col-xl-3"
/>
<Feature
title="Zero Code"
desc="Adding new tables is a matter of configuration, which can perform entirely within the tool itself. No need to define column types, lengths etc these are dynamically figured out at runtime."
Icon={BsCode}
className="col-sm-6 col-md-4 col-xl-3"
/>
<Feature
title="Workflow"
desc="You are able to configure “Hook scripts” to execute before and after each action. So you could run a data quality check after uploading a mapping table or run a model after changing a parameter."
Icon={BiNetworkChart}
className="col-sm-6 col-md-4 col-xl-3"
/>
</div>
</Section>
<Section color="black" bgColor="#f8f8f8">
<div className="row">
<div className="offset-md-2 col-md-8">
<SectionDesc>Take a look at</SectionDesc>
<SectionHeading>Data Controller Design</SectionHeading>
<SectionDesc>
We designed Data Controller to work on multiple devices and
different screen types. This, combined with SAS® scalability and
security, gives you full flexibility and location independence
when managing your data.
</SectionDesc>
<Art src={dcDesign} info="Data Controller Design" />
</div>
</div>
</Section>
<Section color="black" bgColor="white">
<SectionHeading>See How it Looks</SectionHeading>
<Gallery
images={images}
gutter={0}
customWrapper={({ children, onClick }) => (
<ThumbnailWrapper onClick={onClick}>{children}</ThumbnailWrapper>
)}
/>
</Section>
<ScheduleDemo />
</Layout>
)
}
export default Home
export const pageQuery = graphql`
query ImagesForGallery {
images: allFile(
filter: { relativeDirectory: { eq: "gallery" } }
sort: { fields: name }
) {
edges {
node {
childImageSharp {
thumb: gatsbyImageData(
width: 300
height: 270
placeholder: BLURRED
)
full: gatsbyImageData(layout: FULL_WIDTH)
meta: fixed {
originalName
}
}
}
}
}
}
`

View File

@@ -0,0 +1,54 @@
import React from 'react'
import { graphql } from 'gatsby'
import styled from 'styled-components'
import Layout from '../components/layout'
import Seo from '../components/seo'
import { Section } from '../components/shared'
const StyledMarkdown = styled.div`
color: rgb(102, 102, 102);
h2,
h3,
h4,
strong {
color: rgb(34, 34, 34);
}
h2 {
text-transform: uppercase;
letter-spacing: 1px;
font-family: 'Montserrat', 'HelveticaNeue', 'Helvetica Neue', Helvetica,
Arial, sans-serif;
}
`
export default function Template({ data, location }) {
const { frontmatter, html } = data?.markdownRemark
return (
<Layout
location={location}
heading={frontmatter.heading}
desc={frontmatter.desc}
>
<Seo title={frontmatter.title} />
<Section color="black" bgColor="white" bottomArrow={false}>
<StyledMarkdown dangerouslySetInnerHTML={{ __html: html }} />
</Section>
</Layout>
)
}
export const pageQuery = graphql`
query ($id: String!) {
markdownRemark(id: { eq: $id }) {
html
frontmatter {
slug
title
heading
desc
}
}
}
`