This commit is contained in:
Christian Anetzberger
2022-01-29 20:48:35 +01:00
commit 01907eb338
144 changed files with 11275 additions and 0 deletions

15
.babelrc Normal file
View File

@@ -0,0 +1,15 @@
{
"presets": [
"next/babel"
],
"plugins": [
[
"styled-components",
{
"ssr": true,
"displayName": true,
"preprocess": false
}
]
]
}

34
.gitignore vendored Normal file
View File

@@ -0,0 +1,34 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel

34
README.md Normal file
View File

@@ -0,0 +1,34 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

337
assets/landinglogo.ai Normal file

File diff suppressed because one or more lines are too long

229
assets/logo.ai Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

224
components/GogoleMaps.jsx Normal file
View File

@@ -0,0 +1,224 @@
import React from "react";
import { GoogleMap, LoadScript, Marker } from "@react-google-maps/api";
const styles = [
{
featureType: "all",
elementType: "labels",
stylers: [
{
visibility: "off",
},
],
},
{
featureType: "administrative",
elementType: "labels",
stylers: [
{
visibility: "off",
},
],
},
{
featureType: "administrative",
elementType: "labels.text.fill",
stylers: [
{
color: "#444444",
},
{
visibility: "off",
},
],
},
{
featureType: "administrative.neighborhood",
elementType: "labels",
stylers: [
{
visibility: "off",
},
],
},
{
featureType: "landscape",
elementType: "all",
stylers: [
{
visibility: "on",
},
{
color: "#e0dfe0",
},
],
},
{
featureType: "landscape",
elementType: "labels",
stylers: [
{
visibility: "off",
},
],
},
{
featureType: "poi",
elementType: "all",
stylers: [
{
visibility: "off",
},
],
},
{
featureType: "poi",
elementType: "labels",
stylers: [
{
visibility: "off",
},
],
},
{
featureType: "poi.park",
elementType: "geometry",
stylers: [
{
color: "#a8a9a8",
},
{
visibility: "on",
},
],
},
{
featureType: "road",
elementType: "all",
stylers: [
{
saturation: -100,
},
{
lightness: 45,
},
],
},
{
featureType: "road",
elementType: "geometry.fill",
stylers: [
{
visibility: "on",
},
{
color: "#5b5b5a",
},
],
},
{
featureType: "road",
elementType: "labels",
stylers: [
{
visibility: "off",
},
],
},
{
featureType: "road.highway",
elementType: "all",
stylers: [
{
visibility: "simplified",
},
],
},
{
featureType: "road.highway",
elementType: "labels",
stylers: [
{
visibility: "off",
},
],
},
{
featureType: "road.arterial",
elementType: "labels.icon",
stylers: [
{
visibility: "off",
},
],
},
{
featureType: "transit",
elementType: "all",
stylers: [
{
visibility: "off",
},
],
},
{
featureType: "transit",
elementType: "labels",
stylers: [
{
visibility: "off",
},
],
},
{
featureType: "water",
elementType: "all",
stylers: [
{
color: "#ffffff",
},
{
visibility: "on",
},
],
},
{
featureType: "water",
elementType: "labels",
stylers: [
{
visibility: "off",
},
],
},
];
const containerStyle = {
width: "100%",
height: "100%",
};
const center = {
lat: 48.191044224831614,
lng: 11.379406506650541,
};
function GoogleMaps() {
return (
<LoadScript googleMapsApiKey="AIzaSyDx-VOQjrzQcBxWsLXeT9KhihxeQf6TRzY">
<GoogleMap
mapContainerStyle={containerStyle}
center={center}
zoom={17}
options={{
styles: styles,
}}
>
<Marker position={center} label="Hans Prothmann GmbH" />
<></>
</GoogleMap>
</LoadScript>
);
}
export default React.memo(GoogleMaps);

33
components/footer.jsx Normal file
View File

@@ -0,0 +1,33 @@
import Head from "next/head";
import Link from "next/link";
export default function Footer(props) {
return (
<footer>
<div className="container-fluid">
<div className="row py-2">
<div className="col-12 col-lg-4 text-center">
<Link href="/impressum">
<a>Impressum</a>
</Link>
</div>
<div className="col-12 col-lg-4 text-center">
<Link href="/datenschutz">
<a>Datenschutz</a>
</Link>
</div>
<div className="col-12 col-lg-4 text-center">
<Link href="/agbs">
<a>AGBs</a>
</Link>
</div>
</div>
<div className="row footer-dark-bg py-2">
<div className="col-12">
<div className="text-center">© 2021 Prothmann GmbH</div>
</div>
</div>
</div>
</footer>
);
}

View File

@@ -0,0 +1,79 @@
import React, { useEffect, useState } from "react";
import { useDropzone } from "react-dropzone";
const thumbsContainer = {
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
marginTop: 16,
};
const thumb = {
display: "inline-flex",
borderRadius: 2,
border: "1px solid #eaeaea",
marginBottom: 8,
marginRight: 8,
width: 100,
height: 100,
padding: 4,
boxSizing: "border-box",
};
const thumbInner = {
display: "flex",
minWidth: 0,
overflow: "hidden",
};
const img = {
display: "block",
width: "auto",
height: "100%",
};
export default function Dropzone(props) {
const [files, setFiles] = useState([]);
const { getRootProps, getInputProps } = useDropzone({
accept: "image/*,.dxf,.stp,.step,.pdf",
onDrop: (acceptedFiles) => {
props.setFieldValue(
`parts[${props.index}].files`,
props.files.concat(acceptedFiles)
);
setFiles(
props.files.map((file) =>
Object.assign(file, {
preview: URL.createObjectURL(file),
})
)
);
},
});
const thumbs = files.map((file) => (
<div style={thumb} key={file.name}>
<div style={thumbInner}>
<img src={file.preview} style={img} />
</div>
</div>
));
useEffect(
() => () => {
// Make sure to revoke the data uris to avoid memory leaks
files.forEach((file) => URL.revokeObjectURL(file.preview));
},
[files]
);
return (
<section className="container">
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
<aside style={thumbsContainer}>{thumbs}</aside>
</section>
);
}

View File

@@ -0,0 +1,42 @@
import React from "react";
export default class Thumb extends React.Component {
state = {
loading: false,
thumb: undefined,
};
componentDidUpdate(prevProps) {
if (prevProps.file !== this.props.file) {
this.setState({ loading: true }, () => {
let reader = new FileReader();
reader.onloadend = () => {
this.setState({ loading: false, thumb: reader.result });
};
reader.readAsDataURL(this.props.file);
});
}
}
render() {
if (!this.props.file) {
return null;
}
if (this.state.loading) {
return <p>loading...</p>;
}
return (
<img
src={this.state.thumb}
alt={this.props.file.name}
className=""
height={200}
width={200}
/>
);
}
}

View File

@@ -0,0 +1,207 @@
import React from "react";
import {
TextInput,
TextareaInput,
SelectInput,
CheckInput,
} from "../formfields.jsx";
export default function ContactPersonForm(props) {
return (
<>
<div className="row g-2 mb-5">
<div className="col">
<h1>Informationen</h1>
</div>
</div>
<div className="row g-2 mb-5">
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.firma}
touched={props.touched.firma}
placeholder={"Musterfirma"}
onChange={props.handleChange("firma")}
onBlur={props.handleBlur("firma")}
value={props.values.firma}
label="Firma (optional)"
type="text"
/>
</div>
</div>
<div className="row g-2 mb-3">
<h3>Anprechpartner</h3>
<div className="col">
<SelectInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.anrede}
touched={props.touched.anrede}
placeholder={"Anrede"}
onChange={props.handleChange("anrede")}
onBlur={props.handleBlur("anrede")}
value={props.values.anrede}
label="Anrede"
options={["Herr", "Frau", "Divers"]}
/>
</div>
<div className="col">
<SelectInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.titel}
touched={props.touched.titel}
placeholder={"Titel"}
onChange={props.handleChange("titel")}
onBlur={props.handleBlur("titel")}
value={props.values.titel}
label="Titel"
options={["Dr.", "Prof.", "Dipl."]}
/>
</div>
</div>
<div className="row g-2 mb-3">
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.vorname}
touched={props.touched.vorname}
placeholder={"Max"}
onChange={props.handleChange("vorname")}
onBlur={props.handleBlur("vorname")}
value={props.values.vorname}
label="Vorname (optional)"
type="text"
/>
</div>
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.nachname}
touched={props.touched.nachname}
placeholder={"Mustermann"}
onChange={props.handleChange("nachname")}
onBlur={props.handleBlur("nachname")}
value={props.values.nachname}
label="Nachname"
type="text"
/>
</div>
</div>
<div className="row g-2 mb-5">
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.email}
touched={props.touched.email}
placeholder={"max@mustermann.de"}
onChange={props.handleChange("email")}
onBlur={props.handleBlur("email")}
value={props.values.email}
label="eMail"
type="text"
/>
</div>
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.telefon}
touched={props.touched.telefon}
placeholder={"0815 123456"}
onChange={props.handleChange("telefon")}
onBlur={props.handleBlur("telefon")}
value={props.values.telefon}
label="Telfon (optional)"
type="text"
/>
</div>
</div>
<div className="row g-2 mb-3">
<h3>Rechnungsadresse</h3>
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.invoiceadress}
touched={props.touched.invoiceadress}
placeholder={"Musterstraße 1"}
onChange={props.handleChange("invoiceadress")}
onBlur={props.handleBlur("invoiceadress")}
value={props.values.invoiceadress}
label="Adresse"
type="text"
/>
</div>
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.invoiceplz}
touched={props.touched.invoiceplz}
placeholder={"12345"}
onChange={props.handleChange("invoiceplz")}
onBlur={props.handleBlur("invoiceplz")}
value={props.values.invoiceplz}
label="PLZ"
type="text"
/>
</div>
</div>
<div className="row g-2 mb-5">
<div className="col">
<CheckInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.diffrentshipping}
touched={props.touched.diffrentshipping}
onChange={props.handleChange("diffrentshipping")}
onBlur={props.handleBlur("diffrentshipping")}
value={props.values.diffrentshipping}
label=" Lieferadresse ist anders als Rechnungsadresse"
/>
</div>
</div>
{props.values.diffrentshipping && (
<div className="row g-2 mb-5">
<h3>Lieferadresse</h3>
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.shippingaddress}
touched={props.touched.shippingaddress}
placeholder={"Musterstraße 1"}
onChange={props.handleChange("shippingaddress")}
onBlur={props.handleBlur("shippingaddress")}
value={props.values.shippingaddress}
label="Lieferadresse"
type="text"
/>
</div>
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
rescode={props.rescode}
error={props.errors.shippingplz}
touched={props.touched.shippingplz}
placeholder={"12345"}
onChange={props.handleChange("shippingplz")}
onBlur={props.handleBlur("shippingplz")}
value={props.values.shippingplz}
label="PLZ"
type="text"
/>
</div>
</div>
)}
</>
);
}

View File

@@ -0,0 +1,23 @@
import React from "react";
export default function IntroForm(props) {
return (
<>
<div>
<h1>eAnfrage</h1>
<p>
Herzlich Wilkommen bei der Prothman GmbH. Wir freuen uns sehr, dass
Sie Interesse an unserem Produktionsspektrum haben.
<br />
<br />
Hier haben Sie die Möglichkeit, direkt online eine Produktionsanfrage
an uns zu schicken. Dies ist für sie volkommen kostenlos!
<br />
Das Tool erfrgägt alle wichtigen Parameter, die wir für die
Kalkulation eines Angebotes benötigen. Sollten noch Unklarheiten
aufkommen, setzen wir uns mit Ihnen in Verbindung.
</p>
</div>
</>
);
}

View File

@@ -0,0 +1,380 @@
import React from "react";
import {
TextInput,
TextareaInput,
SelectInput,
CheckInput,
} from "../formfields.jsx";
import Image from "next/image";
import Dropzone from "../Dropzone.jsx";
const dropzoneStyle = {
width: "100%",
height: "auto",
borderWidth: 2,
borderColor: "rgb(102, 102, 102)",
borderStyle: "dashed",
borderRadius: 5,
};
export default class PartForm extends React.Component {
constructor(props) {
super(props);
this._handleModalShow = this._handleModalShow.bind(this);
this._handleModalHide = this._handleModalHide.bind(this);
this.state = {
show: false,
modalindex: 0,
newmodaldata: {},
};
}
_handleModalShow(index) {
this.setState({
show: true,
modalindex: index,
});
}
_handleModalHide(index) {
this.setState({
show: false,
});
}
render() {
const that = this;
const props = this.props;
return (
<>
{this.state.show && (
<Overlay
index={this.state.modalindex}
show={this.state.show}
handleHide={this._handleModalHide}
{...props}
/>
)}
<div className="row g-2 mb-5">
<div className="col">
<h1>Produktionsdaten</h1>
</div>
</div>
<div className="row g-2 mb-5">
<div className="col">
<table className="table mt-5">
<thead className="table-secondary">
<tr>
<th>Name</th>
<th>Material</th>
<th>Anzahl</th>
<th>Anzahl Dateien</th>
<th></th>
</tr>
</thead>
<tbody>
{props.values.parts.map(function (part, index) {
return (
<tr key={index}>
<td>{part.name}</td>
<td>{part.material}</td>
<td>{part.amount}</td>
<td>{part.files.length}</td>
<td colSpan="1">
<button
type="button"
className={`btn btn-dark text-center m-0`}
onClick={that._handleModalShow.bind(this, index)}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
className="bi bi-pencil-square"
viewBox="0 0 16 16"
>
<path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456l-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z" />
<path
fillRule="evenodd"
d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z"
/>
</svg>
</button>
<button
type="button"
className={`btn btn-danger text-center m-0`}
onClick={() => console.log("Edit")}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
className="bi bi-x-square"
viewBox="0 0 16 16"
>
<path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h12zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z" />
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" />
</svg>
</button>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</>
);
}
}
function Overlay(props) {
return (
<div className="modal" tabIndex="-1" style={{ display: "block" }}>
<div className="modal-dialog modal-fullscreen">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">
{props.values.parts[props.index]["name"]}
</h5>
<button
type="button"
className="btn-close bg-white"
data-bs-dismiss="modal"
aria-label="Close"
onClick={props.handleHide}
></button>
</div>
<div className="modal-body">
<div className="container">
<div className="row">
<div className="col">
<div className="row g-2 mb-3">
<h3>Angaben</h3>
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
// error={props.errors.parts[props.index]["name"]}
// touched={props.touched.parts[props.index]["name"]}
placeholder={"Metallteil 123"}
onChange={props.handleChange(
`parts[${props.index}].name`
)}
// onBlur={
// props.handleBlur.values.parts[props.index]["name"]
// }
value={props.values.parts[props.index]["name"]}
label="Name"
type="text"
/>
</div>
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
// error={props.errors.parts[props.index]["amount"]}
// touched={props.touched.parts[props.index]["amount"]}
placeholder={"123"}
onChange={props.handleChange(
`parts[${props.index}].amount`
)}
// onBlur={props.handleBlur("amount")}
value={props.values.parts[props.index]["amount"]}
label="Anzahl"
type="text"
/>
</div>
</div>
<div className="row g-2 mb-3">
<div className="col">
<TextareaInput
isSubmitting={props.isSubmitting}
// error={props.errors.parts[props.index]["description"]}
// touched={props.touched.parts[props.index]["description"]}
placeholder={"Metallteil 123"}
onChange={props.handleChange(
`parts[${props.index}].description`
)}
onBlur={props.handleBlur(
`parts[${props.index}].description`
)}
value={props.values.parts[props.index]["description"]}
label="Beschreibung"
type="text"
/>
</div>
</div>
<div className="row g-2 mb-5">
<div className="col">
<SelectInput
isSubmitting={props.isSubmitting}
type="radio"
// error={props.errors.titel}
// touched={props.touched.titel}
placeholder={"Material"}
onChange={props.handleChange(
`parts[${props.index}].material`
)}
onBlur={props.handleBlur(
`parts[${props.index}].material`
)}
value={props.values.parts[props.index]["material"]}
label="Material"
options={[
"1.4301 V2A",
"1.4310 Federstahl",
"1.4404 V4A",
"1.4751 V4A",
"1.4016 Blech",
"DC01 Stahl",
"St37 Stahl",
"AlMg3",
"AlSi",
"Al99",
"Sonstiges",
]}
/>
</div>
{props.values.parts[props.index]["material"] ==
"Sonstiges" && (
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
// error={props.errors.parts[props.index]["materialother"]}
// touched={props.touched.parts[props.index]["materialother"]}
placeholder={"Material (Sonstiges)"}
onChange={props.handleChange(
`parts[${props.index}].materialother`
)}
onBlur={props.handleBlur(
`parts[${props.index}].materialother`
)}
value={
props.values.parts[props.index]["materialother"]
}
label="Material Sonstiges"
type="text"
/>
</div>
)}
</div>
<div className="row g-2 mb-3">
<h3>Oberfläche</h3>
<p>Unsere Teile werden standardmäßig entgratet. </p>
<div className="col">
<SelectInput
isSubmitting={props.isSubmitting}
type="radio"
// error={props.errors.titel}
// touched={props.touched.titel}
placeholder={"Oberfläche"}
onChange={props.handleChange(
`parts[${props.index}].finish`
)}
onBlur={props.handleBlur(
`parts[${props.index}].finish`
)}
value={props.values.parts[props.index]["finish"]}
label="Material"
options={[
"2B matt",
"Oszillationsschliff",
"Gerader Schliff",
"K240 Schliff",
"Sonstiges",
]}
/>
</div>
{props.values.parts[props.index]["finish"] ==
"Sonstiges" && (
<div className="col">
<TextInput
isSubmitting={props.isSubmitting}
// error={props.errors.parts[props.index]["finishother"]}
// touched={props.touched.parts[props.index]["finishother"]}
placeholder={"Oberfläche (Sonstiges)"}
onChange={props.handleChange(
`parts[${props.index}].finishother`
)}
onBlur={props.handleBlur(
`parts[${props.index}].finishother`
)}
value={props.values.parts[props.index]["finishother"]}
label="Oberfläche Sonstiges"
type="text"
/>
</div>
)}
</div>
<div className="row g-2 mb-3">
<h3>Gravur</h3>
<p>Unsere Teile werden standardmäßig entgratet. </p>
<div className="col">
<CheckInput
isSubmitting={props.isSubmitting}
// error={props.errors.diffrentshipping}
// touched={props.touched.diffrentshipping}
onChange={props.handleChange(
`parts[${props.index}].engraving`
)}
onBlur={props.handleBlur(
`parts[${props.index}].engraving`
)}
value={props.values.parts[props.index]["engraving"]}
label=" Dieses Teil soll lasergraviert werden"
/>
</div>
</div>
</div>
<div className="col">
<div className="row g-2 mb-3">
<h3>Dateien</h3>
<p>
Bite fügen Sie alle Dateien in gängigen Formaten (.step,
.pdf) hinzu, die wir für die Produktion benötigen. Die
Produktionsdateien müssen im Maßststab 1:1 sein.
</p>
{props.values.parts[props.index]["engraving"] === true && (
<p>
Zum lasergravieren benötigen wir eine seperate Vektor
Datei (.dwg, .dxf) im Maßstab 1:1, welche nur die zu
gravierenden Formen enthält. Schriften müssen in Pfade
umgewandelt werden!
</p>
)}
<div className="col">
<Dropzone
files={props.values.parts[props.index]["files"]}
setFieldValue={props.setFieldValue}
index={props.index}
/>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-primary"
onClick={props.handleHide}
>
Schließen
</button>
</div>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,10 @@
import React from "react";
import { TextInput, TextareaInput, SelectInput } from "../formfields.jsx";
export default function Summary(props) {
return (
<>
<h1>Übersicht</h1>
</>
);
}

View File

@@ -0,0 +1,110 @@
import React from "react";
export function TextInput(props) {
return (
<>
<div className="form-floating">
<input
disabled={props.isSubmitting || props.rescode === 200}
type={props.type}
className={`form-control ${
props.error && props.touched ? "is-invalid" : ""
} ${!props.error && props.touched ? "is-valid" : ""}`}
placeholder={props.placeholder}
onChange={props.onChange}
onBlur={props.onBlur}
value={props.value}
/>
<label>{props.label}</label>
</div>
{props.error && props.touched ? (
<div className="invalid-feedback" style={{ display: "block" }}>
{props.error}
</div>
) : null}
</>
);
}
export function TextareaInput(props) {
return (
<>
<div className="form-floating">
<textarea
disabled={props.isSubmitting || props.rescode === 200}
style={{ height: "100px", resize: "none" }}
className={`form-control ${
props.error && props.touched ? "is-invalid" : ""
} ${!props.error && props.touched ? "is-valid" : ""}`}
placeholder={props.placeholder}
onChange={props.onChange}
onBlur={props.onBlur}
value={props.value}
/>
<label>{props.label}</label>
</div>
{props.error && props.touched ? (
<div className="invalid-feedback" style={{ display: "block" }}>
{props.error}
</div>
) : null}
</>
);
}
export function SelectInput(props) {
return (
<>
<div className="form-floating">
<select
disabled={props.isSubmitting || props.rescode === 200}
onChange={props.onChange}
onBlur={props.onBlur}
className={`form-control ${
props.error && props.touched ? "is-invalid" : ""
} ${!props.error && props.touched ? "is-valid" : ""}`}
>
<option defaultValue></option>
{props.options.map(function (option) {
return (
<option key={option} value={option}>
{option}
</option>
);
})}
</select>
<label>{props.label}</label>
</div>
{props.error && props.touched ? (
<div className="invalid-feedback" style={{ display: "block" }}>
{props.error}
</div>
) : null}
</>
);
}
export function CheckInput(props) {
return (
<>
<div className="form-check text-start">
<input
disabled={props.isSubmitting || props.rescode === 200}
type={props.type || "checkbox"}
className={`form-check-input ${
props.error && props.touched ? "is-invalid" : ""
} ${!props.error && props.touched ? "is-valid" : ""}`}
onChange={props.onChange}
onBlur={props.onBlur}
value={props.value}
/>
<label className="form-check-label">{props.label}</label>
</div>
{props.error && props.touched ? (
<div className="invalid-feedback" style={{ display: "block" }}>
{props.error}
</div>
) : null}
</>
);
}

View File

@@ -0,0 +1,49 @@
import * as Yup from "yup";
export const ContactSchema = Yup.object().shape({
firma: Yup.string().max(64, "Maximal 64 Zeichen"),
anrede: Yup.string()
.min(2, "Mindestens 2 Zeichen")
.max(64, "Maximal 64 Zeichen")
.required("Pflichtfeld"),
titel: Yup.string().max(64, "Maximal 64 Zeichen"),
vorname: Yup.string().max(64, "Maximal 64 Zeichen"),
nachname: Yup.string()
.min(2, "Mindestens 2 Zeichen")
.max(64, "Maximal 64 Zeichen")
.required("Pflichtfeld"),
email: Yup.string().email("Ungültige Email Adresse").required("Pflichtfeld"),
telefon: Yup.string()
.min(2, "Mindestens 2 Zeichen")
.max(64, "Maximal 64 Zeichen"),
betreff: Yup.string()
.min(5, "Mindestens 5 Zeichen")
.max(64, "Maximal 64 Zeichen")
.required("Pflichtfeld"),
nachricht: Yup.string()
.min(10, "Mindestens 10 Zeichen")
.max(2000, "Maximal 2000 Zeichen")
.required("Pflichtfeld"),
});
export const EanfrageSchema = Yup.object().shape({
firma: Yup.string().max(64, "Maximal 64 Zeichen"),
anrede: Yup.string()
.min(2, "Mindestens 2 Zeichen")
.max(64, "Maximal 64 Zeichen")
.required("Pflichtfeld"),
titel: Yup.string().max(64, "Maximal 64 Zeichen"),
vorname: Yup.string().max(64, "Maximal 64 Zeichen"),
nachname: Yup.string()
.min(2, "Mindestens 2 Zeichen")
.max(64, "Maximal 64 Zeichen")
.required("Pflichtfeld"),
email: Yup.string().email("Ungültige Email Adresse").required("Pflichtfeld"),
telefon: Yup.string()
.min(2, "Mindestens 2 Zeichen")
.max(64, "Maximal 64 Zeichen"),
invoiceadress: Yup.string()
.min(2, "Mindestens 2 Zeichen")
.max(64, "Maximal 64 Zeichen"),
invoiceplz: Yup.number("PLZ kann nur Zahlen enthalten"),
});

21
components/media/logo.jsx Normal file
View File

@@ -0,0 +1,21 @@
export default function HomeLanding() {
return (
<svg
id="Layer_1"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 595.28 841.89"
>
<title>hp_logo</title>
<rect className="logo-style-1" width="595.28" height="841.89" />
<polygon
className="logo-style-2"
points="255.88 38.58 255.88 181.67 169.88 181.67 169.88 38.58 88.02 38.58 88.02 406.61 169.88 406.61 169.88 263.53 255.88 263.53 255.88 406.61 337.74 406.61 337.74 38.58 255.88 38.58"
/>
<path
className="logo-style-2"
d="M466.09,436.93H255.88V805h81.86V687.36H505.6V436.93ZM337.74,605.5V518.79h86V605.5Z"
/>
</svg>
);
}

View File

@@ -0,0 +1,103 @@
import React from "react";
export const QualityIcon1 = () => (
<svg
id="Layer_1"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
width="500"
height="500"
viewBox="0 0 500 500"
>
<title>qualityIcon1</title>
<g id="qualityIcon1" data-name="1">
<path
className="cls-1"
d="M464.4,373.62a11.81,11.81,0,0,0,11.78-11.78V131.26a11.81,11.81,0,0,0-11.78-11.78H29.72A11.8,11.8,0,0,0,18,131.26V361.84a11.8,11.8,0,0,0,11.77,11.78H339.79"
/>
<circle className="cls-1" cx="402.09" cy="350.56" r="51.51" />
<circle className="cls-1" cx="402.09" cy="350.56" r="36.8" />
<polyline
className="cls-1"
points="357.45 375.58 321.63 411.39 340.77 410.9 340.77 431 376.33 395.44"
/>
<polyline
className="cls-1"
points="446.74 375.58 482.56 411.39 463.42 410.9 463.42 431 427.86 395.44"
/>
<line className="cls-1" x1="80.74" y1="159.71" x2="302.5" y2="159.71" />
<line className="cls-1" x1="80.74" y1="198.96" x2="106.26" y2="198.96" />
<line className="cls-1" x1="148.45" y1="198.96" x2="407.49" y2="198.96" />
<line className="cls-1" x1="80.74" y1="238.21" x2="302.5" y2="238.21" />
<line className="cls-1" x1="80.74" y1="277.46" x2="302.5" y2="277.46" />
<line className="cls-1" x1="329.97" y1="277.46" x2="355.49" y2="277.46" />
<line className="cls-1" x1="238.72" y1="336.33" x2="334.88" y2="336.33" />
</g>
</svg>
);
export const QualityIcon2 = () => (
<svg
id="qualityIcon2"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
width="500"
height="500"
viewBox="0 0 500 500"
>
<title>qualityIcon2</title>
<g id="_1" data-name="1">
<rect
className="cls-1"
x="-36.48"
y="193.17"
width="572.35"
height="114.47"
transform="translate(-103.93 249.9) rotate(-45)"
/>
<line className="cls-1" x1="209.22" y1="209.94" x2="249.69" y2="250.41" />
<line className="cls-1" x1="377.85" y1="41.3" x2="398.09" y2="61.54" />
<line className="cls-1" x1="242.95" y1="176.21" x2="263.18" y2="196.44" />
<line className="cls-1" x1="276.67" y1="142.48" x2="296.91" y2="162.72" />
<line className="cls-1" x1="344.13" y1="75.03" x2="364.36" y2="95.27" />
<line className="cls-1" x1="310.4" y1="108.76" x2="350.87" y2="149.23" />
<line className="cls-1" x1="108.04" y1="311.11" x2="148.52" y2="351.58" />
<line className="cls-1" x1="141.77" y1="277.39" x2="162.01" y2="297.62" />
<line className="cls-1" x1="175.5" y1="243.66" x2="195.73" y2="263.9" />
<line className="cls-1" x1="40.59" y1="378.57" x2="60.83" y2="398.8" />
<line className="cls-1" x1="74.32" y1="344.84" x2="94.55" y2="365.08" />
</g>
</svg>
);
export const QualityIcon3 = () => (
<svg
id="qualityIcon3"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
width="500"
height="500"
viewBox="0 0 500 500"
>
<title>qualityIcon3</title>
<rect
className="cls-1"
x="17.5"
y="116.75"
width="467"
height="259"
rx="12"
ry="12"
/>
<g>
<path className="cls-3" d="M105.3,318.08v-144h13.6v144Z" />
<path
className="cls-3"
d="M161.7,275.08a42.68,42.68,0,0,0,4.3,16.3,32.14,32.14,0,0,0,9,10.9,35.75,35.75,0,0,0,12.7,6.1,60,60,0,0,0,15.4,1.9,51.33,51.33,0,0,0,16.6-2.4,31.39,31.39,0,0,0,11.4-6.5,25.51,25.51,0,0,0,6.5-9.5,31.17,31.17,0,0,0,2.1-11.4q0-8.4-3.8-13.6a29.21,29.21,0,0,0-9.9-8.5,60.44,60.44,0,0,0-14-5.3q-7.91-2-16.2-3.9t-16.2-4.5a51,51,0,0,1-14-7,33.73,33.73,0,0,1-9.9-11.3q-3.8-6.9-3.8-17.5a35.19,35.19,0,0,1,3.1-14.4,35.83,35.83,0,0,1,9.2-12.4,45.16,45.16,0,0,1,15.3-8.6,64.5,64.5,0,0,1,21.2-3.2,60.71,60.71,0,0,1,21.3,3.4,42.36,42.36,0,0,1,15.1,9.3,38.25,38.25,0,0,1,9,13.7,45.83,45.83,0,0,1,3,16.6h-13a32.36,32.36,0,0,0-2.9-14.2,26.61,26.61,0,0,0-7.9-9.8,33.73,33.73,0,0,0-11.4-5.6,48.56,48.56,0,0,0-13.2-1.8q-10.39,0-17.5,2.9a30.69,30.69,0,0,0-11.3,7.5,25.41,25.41,0,0,0-5.8,10.2,24.46,24.46,0,0,0-.6,11.2,19.55,19.55,0,0,0,5.6,11.2,35.26,35.26,0,0,0,10.8,6.9,81.27,81.27,0,0,0,14.1,4.4q7.69,1.69,15.7,3.6t15.5,4.5a47.69,47.69,0,0,1,13.3,7,32.14,32.14,0,0,1,9.3,11.3q3.49,6.9,3.5,17.3,0,20-13.8,31t-38.8,11a71.72,71.72,0,0,1-20.8-2.9,46.11,46.11,0,0,1-16.6-8.8,40.36,40.36,0,0,1-10.9-14.6q-3.9-8.7-3.9-20.5Z"
/>
<path
className="cls-3"
d="M272.7,246.28a98.89,98.89,0,0,1,4.3-29.6,71.27,71.27,0,0,1,12.7-24.1,60.32,60.32,0,0,1,20.8-16.3q12.4-6,28.6-6,16.8,0,29.5,5.9a59.54,59.54,0,0,1,21.2,16.2,70.26,70.26,0,0,1,12.8,24.2,100.22,100.22,0,0,1,4.3,29.7,97.51,97.51,0,0,1-4.3,29.3,71.45,71.45,0,0,1-12.7,24,59.86,59.86,0,0,1-21,16.3q-12.6,6-29.2,6t-29.2-6a59.86,59.86,0,0,1-21-16.3,70,70,0,0,1-12.6-24A99.44,99.44,0,0,1,272.7,246.28Zm67.2,64q14,0,24.1-5.3a48,48,0,0,0,16.6-14.1,60.23,60.23,0,0,0,9.6-20.4,93.18,93.18,0,0,0,3.1-24.2,90.37,90.37,0,0,0-3.7-26.9,58.38,58.38,0,0,0-10.7-20.3,45.87,45.87,0,0,0-17-12.8,55.1,55.1,0,0,0-22.4-4.4q-13.8,0-23.9,5.4a48.65,48.65,0,0,0-16.6,14.3,61.09,61.09,0,0,0-9.6,20.5,96.79,96.79,0,0,0,0,48.6,60,60,0,0,0,9.6,20.4,47.11,47.11,0,0,0,16.6,14Q325.69,310.29,339.9,310.28Z"
/>
</g>
</svg>
);

View File

@@ -0,0 +1,278 @@
import React from "react";
export const ServiceIcon1 = () => (
<svg
id="Layer_1"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 500 500"
>
<title>serviceIcons</title>
<g id="_1" data-name="1">
<polyline
className="cls-1"
points="173.7 208.12 9 322.7 110.74 393.47 212.35 318.1"
/>
<polyline
className="cls-1"
points="290.91 318.1 147.48 419.03 249.5 490 490 322.7 325.27 208.1"
/>
<polyline
className="cls-1"
points="197.22 134.48 144.94 82.2 144.94 9 9 9"
/>
<polyline
className="cls-1"
points="490 9 354.06 9 354.06 82.2 301.78 134.48 228.59 134.48"
/>
<line className="cls-1" x1="354.07" y1="318.09" x2="290.91" y2="318.09" />
<line className="cls-1" x1="212.35" y1="318.09" x2="134.48" y2="318.09" />
<line className="cls-1" x1="209.87" y1="288.5" x2="164.8" y2="266.75" />
<line className="cls-1" x1="334.2" y1="266.75" x2="289.13" y2="288.5" />
<line className="cls-1" x1="249.5" y1="218.13" x2="249.5" y2="301.78" />
<polyline
className="cls-1"
points="197.22 134.48 197.22 186.76 236.43 218.13 262.57 218.13 301.78 186.76 301.78 134.48"
/>
</g>
</svg>
);
export const ServiceIcon2 = () => (
<svg
id="Layer_1"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 500 500"
>
<title>serviceIcons</title>
<g id="_2" data-name="2">
<g id="_1" data-name="1">
<polyline
className="cls-1"
points="173.7 209.12 9 323.7 110.74 394.47 147.48 420.03 249.5 491 490 323.7 325.27 209.1"
/>
<polyline
className="cls-1"
points="354.06 10 354.06 83.2 285.5 151.5 285.5 217.5 213.5 217.5 213.5 151.5 144.5 80.5 144.94 10"
/>
</g>
<ellipse className="cls-1" cx="249.5" cy="321" rx="43.85" ry="33.5" />
</g>
</svg>
);
export const ServiceIcon3 = () => (
<svg
id="Layer_1"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 500 500"
>
<title>serviceIcons</title>
<g id="_3" data-name="3">
<line className="cls-1" x1="9.5" y1="490.5" x2="490.5" y2="490.5" />
<line className="cls-1" x1="249.5" y1="9.5" x2="490.5" y2="9.5" />
<line className="cls-1" x1="9.5" y1="9.5" x2="203.5" y2="9.5" />
</g>
<line className="cls-1" x1="249.5" y1="250.5" x2="231.5" y2="232.5" />
<path
className="cls-1"
d="M203.5,98.5l6.13,6.13A105.76,105.76,0,0,1,238.17,202L231.5,232.5"
/>
<line className="cls-1" x1="203.5" y1="9.5" x2="203.5" y2="98.5" />
<path
className="cls-1"
d="M299.5,9.5l.86,78.29a75.23,75.23,0,0,0,3.22,21l6,19.86A79.23,79.23,0,0,1,308,179.86a98.35,98.35,0,0,1-22.33,34.45L249.5,250.5"
/>
<line className="cls-1" x1="249.5" y1="408.5" x2="203.5" y2="362.5" />
<line className="cls-1" x1="249.5" y1="408.5" x2="295.5" y2="362.5" />
<line className="cls-1" x1="203.5" y1="362.5" x2="9.5" y2="362.5" />
<line className="cls-1" x1="295.5" y1="362.5" x2="490.5" y2="362.5" />
<line className="cls-1" x1="249.5" y1="348.5" x2="163" y2="262" />
<line className="cls-1" x1="250" y1="348.5" x2="336.5" y2="262" />
</svg>
);
export const ServiceIcon4 = () => (
<svg
id="Layer_1"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 500 500"
>
<title>serviceIcons</title>
<g id="_4" data-name="4">
<path
className="cls-1"
d="M189.76,184.55,86.4,421.15a23.84,23.84,0,0,1-18.18,14L45.6,438.68v51.64l135.93.18V440.11l-4-.44a23.83,23.83,0,0,1-19.82-31.77l8.2-22.71h88.67l9.56,21.09a23.85,23.85,0,0,1-19.85,33.6h0V490.5H401.12V439.41l-22.7-1.61a23.85,23.85,0,0,1-20.18-14.29L300.91,291.27M192,333.65l23.26-55.44,23.23,55.44Z"
/>
<line className="cls-1" x1="307.01" y1="265.68" x2="307.01" y2="202.95" />
<line className="cls-1" x1="307.01" y1="119.29" x2="307.01" y2="56.55" />
<line className="cls-1" x1="380.94" y1="229.82" x2="339.11" y2="187.99" />
<line className="cls-1" x1="280.14" y1="129.02" x2="233.08" y2="81.96" />
<line className="cls-1" x1="411.58" y1="155.89" x2="348.52" y2="155.89" />
<line className="cls-1" x1="265.5" y1="155.89" x2="202.45" y2="155.89" />
<line className="cls-1" x1="233.07" y1="229.83" x2="274.91" y2="187.99" />
<line className="cls-1" x1="306.85" y1="156.05" x2="453.4" y2="9.5" />
</g>
</svg>
);
export const ServiceIcon5 = () => (
<svg
id="Layer_1"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 500 500"
>
<title>serviceIcons</title>
<g id="_5" data-name="5">
<path
className="cls-1"
d="M9,9H293.5a50,50,0,0,1,50,50V340h-188V121.84a50,50,0,0,0-50-50H9Z"
/>
<polygon
className="cls-1"
points="271.44 211.5 227.56 211.5 205.62 249.5 227.56 287.5 271.44 287.5 293.38 249.5 271.44 211.5"
/>
<path
className="cls-1"
d="M489.5,490H205a50,50,0,0,1-50-50V340H343v37.16a50,50,0,0,0,50,50h96.5Z"
/>
</g>
</svg>
);
export const ServiceIcon6 = () => (
<svg
id="Layer_1"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 500 500"
>
<title>serviceIcons</title>
<g id="_6" data-name="6">
<g>
<polyline
className="cls-1"
points="329.67 190.33 329.67 169.33 308.67 169.33"
/>
<line
className="cls-2"
x1="269.22"
y1="169.33"
x2="210.06"
y2="169.33"
/>
<polyline
className="cls-1"
points="190.33 169.33 169.33 169.33 169.33 190.33"
/>
<line
className="cls-2"
x1="169.33"
y1="229.78"
x2="169.33"
y2="288.94"
/>
<polyline
className="cls-1"
points="169.33 308.67 169.33 329.67 190.33 329.67"
/>
<line
className="cls-2"
x1="229.78"
y1="329.67"
x2="288.94"
y2="329.67"
/>
<polyline
className="cls-1"
points="308.67 329.67 329.67 329.67 329.67 308.67"
/>
<line
className="cls-2"
x1="329.67"
y1="269.22"
x2="329.67"
y2="210.06"
/>
</g>
<polygon
className="cls-1"
points="169.33 169.33 9 169.33 9 329.67 169.33 329.67 169.33 490 329.67 490 329.67 329.67 490 329.67 490 169.33 329.67 169.33 329.67 9 169.33 9 169.33 169.33"
/>
</g>
</svg>
);
export const ServiceIcon7 = () => (
<svg
id="Layer_1"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 500 500"
>
<title>serviceIcons</title>
<g id="_7" data-name="7">
<rect
className="cls-1"
x="123.5"
y="93.5"
width="252"
height="70"
rx="12"
ry="12"
/>
<path
className="cls-1"
d="M297.45,356.06a15.68,15.68,0,0,1,0-22.17l3.33-3.32a15.68,15.68,0,0,1,22.17,0l77.75,77.75a179.9,179.9,0,0,0,29.57-99.09V59a50,50,0,0,0-50-50H118.73a50,50,0,0,0-50,50V307.25c0,105.61,86.36,188.75,191.78,182.42a180.17,180.17,0,0,0,117.37-53.18Z"
/>
<polyline
className="cls-1"
points="298.03 331.14 240.26 273.37 221.97 291.66"
/>
<path
className="cls-1"
d="M188.11,297.16,144,370l72.81-44.11a8,8,0,0,0,3.11-1.89c4.9-4.9,2.17-15.57-6.09-23.83s-18.94-11-23.83-6.1A7.92,7.92,0,0,0,188.11,297.16Z"
/>
</g>
</svg>
);
export const ServiceIcon8 = () => (
<svg
id="Layer_1"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 500 500"
>
<title>serviceIcons</title>
<g id="_8" data-name="8">
<rect
className="cls-1"
x="9"
y="105.44"
width="481"
height="193.13"
rx="96.56"
/>
<circle className="cls-1" cx="103.74" cy="201.39" r="53.44" />
<circle className="cls-1" cx="396.47" cy="201.39" r="53.44" />
<circle className="cls-1" cx="249.5" cy="342.5" r="11" />
<circle className="cls-1" cx="299.5" cy="342.5" r="11" />
<circle className="cls-1" cx="149.5" cy="342.5" r="11" />
<circle className="cls-1" cx="349.5" cy="342.5" r="11" />
<circle className="cls-1" cx="99.5" cy="342.5" r="11" />
<circle className="cls-1" cx="399.5" cy="342.5" r="11" />
<circle className="cls-1" cx="274.5" cy="382.5" r="11" />
<circle className="cls-1" cx="199.5" cy="342.5" r="11" />
<circle className="cls-1" cx="324.5" cy="382.5" r="11" />
<circle className="cls-1" cx="374.5" cy="382.5" r="11" />
<circle className="cls-1" cx="224.5" cy="382.5" r="11" />
<circle className="cls-1" cx="174.5" cy="382.5" r="11" />
<circle className="cls-1" cx="124.5" cy="382.5" r="11" />
</g>
</svg>
);

272
components/navbar.jsx Normal file
View File

@@ -0,0 +1,272 @@
import React from "react";
import Image from "next/image";
import { withRouter } from "next/router";
import { gsap } from "gsap/dist/gsap";
import { ScrollTrigger } from "gsap/dist/ScrollTrigger.js";
import Link from "next/link";
import Logo from "./media/logo.jsx";
gsap.registerPlugin(ScrollTrigger);
class Navbar extends React.Component {
constructor(props) {
super(props);
this.toggle = this.toggle.bind(this);
this.toggleClose = this.toggleClose.bind(this);
this.isLg = this.isLg.bind(this);
this.state = {
isOpen: false,
menuitems: [
{
key: 0,
name: "Home",
link: "/",
},
{
key: 1,
name: "Fertigungsverfahren",
link: "/fertigungsverfahren",
},
{
key: 2,
name: "Materialien",
link: "/materialien",
},
{
key: 3,
name: "Qualität",
link: "/qualitaet",
},
{
key: 4,
name: "Branchen",
link: "/branchen",
},
{
key: 5,
name: "Kontakt",
link: "/kontakt",
},
{
key: 6,
name: "eAnfrage",
link: "/eanfrage",
},
],
submenuServices: [
{
key: 0,
name: "Laserteile",
link: "laserteile",
isActive: false,
icon: "/icons/fertigungsverfahren/laserteile.svg",
alt: "Laserteile Icon",
},
{
key: 1,
name: "Stanzteile",
link: "stanzteile",
isActive: false,
icon: "/icons/fertigungsverfahren/stanzteile.svg",
alt: "Stanzteile Icon",
},
{
key: 2,
name: "Biegeteile",
link: "biegeteile",
isActive: false,
icon: "/icons/fertigungsverfahren/biegeteile.svg",
alt: "Biegeteile Icon",
},
{
key: 3,
name: "Lasergravur",
link: "lasergravur",
isActive: false,
icon: "/icons/fertigungsverfahren/lasergravur.svg",
alt: "Lasergravur Icon",
},
{
key: 4,
name: "Blechkonstruktionen",
link: "blechkonstruktion",
isActive: false,
icon: "/icons/fertigungsverfahren/metallkonstruktion.svg",
alt: "Blechkonstruktionen Icon",
},
{
key: 5,
name: "Baugruppen",
link: "baugruppe",
isActive: false,
icon: "/icons/fertigungsverfahren/baugruppe.svg",
alt: "Baugruppen Icon",
},
{
key: 6,
name: "Fügeverfahren",
link: "fügeverfahren",
isActive: false,
icon: "/icons/fertigungsverfahren/fuegeverfahren.svg",
alt: "Fügeverfahren Icon",
},
{
key: 7,
name: "Entgrattechnik",
link: "entgraten",
isActive: false,
icon: "/icons/fertigungsverfahren/entgraten.svg",
alt: "Entgrattechnik Icon",
},
],
};
}
componentDidUpdate(props, prevProps) {
if (this.props.isOpen !== prevProps.isOpen) {
if (this.state.isOpen) {
gsap.to(".navbar-collapse", {
height: "auto",
});
} else if (!this.state.isOpen) {
if (!this.isLg()) {
gsap.to(".navbar-collapse", {
height: 0,
});
}
}
}
}
toggle() {
this.setState({
isOpen: !this.state.isOpen,
});
}
toggleClose() {
this.setState({
isOpen: false,
});
}
isLg() {
if (
(self.innerWidth && self.innerWidth >= 992) ||
(document.documentElement &&
document.documentElement.clientWidth &&
document.documentElement.clientWidth >= 992) ||
(document.body && document.body.clientWidth >= 992)
) {
return true;
} else {
return false;
}
}
componentDidMount() {
if (!this.isLg()) {
gsap.set(".navbar-collapse", {
height: 0,
});
}
let targets = gsap.utils.toArray(".subnav-container div");
gsap
.timeline({
scrollTrigger: {
trigger: "body",
start: "top+=200 top",
end: "+=300",
scrub: 0.1,
},
})
.to(".subnav-container", {
height: 0,
ease: "power1.inOut",
})
.to(
targets,
{
opacity: 0,
ease: "power4.inOut",
},
0
);
}
render() {
const pathname = this.props.router.pathname;
return (
<>
<nav
className="noselect navbar navbar-expand-lg fixed-top"
onToggle={this.toggle}
>
<Link href="/" onClick={this.toggleClose}>
<a className="navbar-brand">
<Logo />
</a>
</Link>
<button
onClick={this.toggle}
className="navbar-toggler"
type="button"
>
<div
className={
this.state.isOpen ? "animated-icon open" : "animated-icon"
}
>
<span />
<span />
<span />
<span />
</div>
</button>
<div className="mainnav-container d-flex justify-content-around">
<div className="navbar-collapse">
<div className="navbar-nav">
{this.state.menuitems.map((menuitem, index) => (
<div key={menuitem.key} className="nav-item">
<Link href={menuitem.link}>
<a onClick={this.toggleClose}>{menuitem.name}</a>
</Link>
</div>
))}
</div>
</div>
</div>
<div className="subnav-container d-flex flex-row flex-nowrap align-items-center">
{this.state.submenuServices.map((menuitem, index) => (
<div key={menuitem.key} className="nav-subitem">
<Link
href={"/fertigungsverfahren/" + menuitem.link}
className="nav-link"
>
<a>
<Image
src={menuitem.icon}
alt={menuitem.alt}
layout="intrinsic"
width={50}
height={50}
/>
<div>{menuitem.name}</div>
</a>
</Link>
</div>
))}
</div>
</nav>
</>
);
}
}
export default withRouter(Navbar);

View File

@@ -0,0 +1,34 @@
import React from "react";
import { ReactSVG } from "react-svg";
export default function Productpage(props) {
return (
<>
<div className="container-fluid products-container navbar-spacing">
<div className="row align-items-center min-height-100">
<div
className={`align-self-stretch background-image d-flex flex-column justify-content-center products-img-shadow products-img ${
props.reversed ? "order-lg-1" : ""
} ${props.smallbg ? "col-lg-5" : "col-lg-6"}`}
style={{ backgroundImage: `url(${props.bgurl})` }}
>
<div className="icon-size align-items-center">
<ReactSVG src={props.iconurl} />
</div>
</div>
<div
className={`col-lg-6 pl-0 align-self-center p-5 mb-5 h-100 ${
props.smallbg ? "col-lg-7" : "col-lg-6"
}`}
>
<h1 className="mainheading">{props.title}</h1>
<div className="description">
<p dangerouslySetInnerHTML={{ __html: props.text }}></p>
{props.addtext && props.addtext}
</div>
</div>
</div>
</div>
</>
);
}

View File

@@ -0,0 +1,25 @@
import Image from "next/image";
export default function ProductContainer(props) {
return (
<div className="col-12 col-lg-4 text-center h-100">
<div className="content">
<div className="bg-white">
<Image
src={props.imgurl}
alt={props.imgalt}
className="p-3"
layout="intrinsic"
width={300}
height={300}
/>
</div>
<div className="">
<h3 className="text-center">{props.title}</h3>
<p>{props.text}</p>
{props.children}
</div>
</div>
</div>
);
}

24
components/utils.jsx Normal file
View File

@@ -0,0 +1,24 @@
export function getWidth() {
if (typeof window != "undefined") {
return Math.max(
document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth
);
}
return 0;
}
export function getHeight() {
if (typeof window != "undefined") {
return Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight,
document.body.offsetHeight,
document.documentElement.offsetHeight,
document.documentElement.clientHeight
);
}
}

View File

@@ -0,0 +1,28 @@
module.exports = {
apps : [{
name: "www.canetzberger.design",
script: "yarn start",
env: {
NODE_ENV: "development",
MAIL_DOMAIN: "mail.example.com",
MAIL_PORT: 587,
MAIL_USER:"mailuser",
MAIL_PASS:"mailpass",
MAIL_REJECTUNAUTHORIZED:false,
MAIL_IGNORETLS:false,
MAIL_REQUIRETLS:true,
MAIL_TO: "info@example.com"
},
env_production: {
NODE_ENV: "production",
MAIL_DOMAIN: "mail.example.com",
MAIL_PORT: 587,
MAIL_USER:"mailuser",
MAIL_PASS:"mailpass",
MAIL_REJECTUNAUTHORIZED:false,
MAIL_IGNORETLS:false,
MAIL_REQUIRETLS:true,
MAIL_TO: "info@example.com"
}
}]
}

34
next.config.js Normal file
View File

@@ -0,0 +1,34 @@
const path = require("path");
const withPlugins = require("next-compose-plugins");
const optimizedImages = require("next-optimized-images");
module.exports = withPlugins([
[
optimizedImages,
{
mozjpeg: {
quality: 70,
},
svgo: {
plugins: [{ removeComments: false }],
},
},
],
{
sassOptions: {
includePaths: [path.join(__dirname, "styles")],
},
async rewrites() {
return [
{
source: "/fertigungsverfahren",
destination: "/fertigungsverfahren/laserteile",
},
{
source: "/qualitaet",
destination: "/qualitaet/auszeichnungen",
},
];
},
},
]);

BIN
node_addons/gsap-bonus.tgz Normal file

Binary file not shown.

44
package.json Normal file
View File

@@ -0,0 +1,44 @@
{
"name": "www.prothmann.com",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"start": "next start -p 3001",
"build": "NODE_ENV=production next build",
"update": "ncu -u && yarn install",
"deploy": "git pull && yarn install && yarn build && pm2 restart 0"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14",
"@fullhuman/postcss-purgecss": "^4.0.3",
"@react-google-maps/api": "^2.1.1",
"axios": "^0.21.1",
"babel-plugin-styled-components": "^1.12.0",
"bootstrap": "^5.0.0-beta2",
"bootstrap-icons": "^1.4.0",
"classnames": "^2.2.6",
"formik": "^2.2.6",
"gsap": "file:./node_addons/gsap-bonus.tgz",
"imagemin-mozjpeg": "^9.0.0",
"imagemin-svgo": "^9.0.0",
"next": "10.0.9",
"next-compose-plugins": "^2.2.1",
"next-optimized-images": "^2.6.2",
"nodemailer": "^6.5.0",
"postcss": "^8.2.8",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-preset-env": "^6.7.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-dropzone": "^11.3.2",
"react-svg": "^12.1.0",
"react-transition-group": "^4.4.1",
"sass": "^1.32.8",
"styled-components": "^5.2.1",
"webpack": "^5.28.0",
"yup": "^0.32.9"
}
}

224
pages/_app.js Normal file
View File

@@ -0,0 +1,224 @@
import App, { Container } from "next/app";
import Router from "next/router";
import Head from "next/head";
import { gsap } from "gsap/dist/gsap";
import { SplitText } from "gsap/dist/SplitText";
import { Transition, SwitchTransition } from "react-transition-group";
// component imports
import Footer from "../components/footer.jsx";
import Navbar from "../components/navbar.jsx";
import { getWidth } from "../components/utils.jsx";
// css imports
import "bootstrap/dist/css/bootstrap.css";
import "../styles/globals.scss";
import "../styles/footer.scss";
import "../styles/navbar.scss";
import "../styles/darkmode.scss";
gsap.registerPlugin(SplitText);
export default class Site extends App {
constructor(props) {
super(props);
this.handleEnter = this.handleEnter.bind(this);
this.handleExit = this.handleExit.bind(this);
this.initTl = this.initTl.bind(this);
this.tl = gsap.timeline();
this.state = {
isReady: true,
};
}
initTl() {
if (document.querySelector(".landing-img")) {
this.tl.from(".landing-img", {
opacity: 0,
});
}
if (document.querySelector(".products-img")) {
if (getWidth() > 1200) {
this.tl.from(".products-img", {
opacity: 0,
width: "100vw",
});
} else {
this.tl.from(".products-img", {
opacity: 0,
height: "100vh",
});
}
}
if (document.querySelector(".mainheading")) {
this.tl.from(".mainheading", {
opacity: 0,
y: 5,
});
}
if (document.querySelector(".subheading")) {
this.tl.from(".subheading", {
opacity: 0,
y: 5,
});
}
if (document.querySelector(".description")) {
this.tl.from(
".description",
{
opacity: 0,
y: 5,
},
0.6
);
}
if (document.querySelector(".quicknav")) {
this.tl.from(".quicknav", {
opacity: 0,
x: -50,
});
}
}
handleEnter() {
this.initTl();
this.tl.play();
this.setState({
isReady: true,
});
}
handleExit(node, done) {
this.setState({
isReady: false,
});
this.tl.clear();
if (document.querySelector(".mainheading")) {
this.tl.to(".mainheading", {
opacity: 0,
duration: 0.2,
});
}
if (document.querySelector(".description")) {
this.tl.to(
".description",
{
opacity: 0,
duration: 0.2,
},
0
);
}
if (document.querySelector(".products-img")) {
if (getWidth() > 1200) {
this.tl.to(
".products-img",
{
opacity: 0,
width: 0,
duration: 0.5,
},
0
);
} else {
this.tl.to(
".products-img",
{
opacity: 0,
height: 0,
minHeight: 0,
duration: 0.5,
},
0
);
}
}
if (document.querySelector(".landing-img")) {
this.tl.to(".landing-img", {
scale: 0.9,
opacity: 0,
});
}
this.tl.to(node, {
opacity: 0,
duration: 0.1,
onComplete: done,
});
}
render() {
const { Component, pageProps, router } = this.props;
let path = router.asPath;
return (
<>
<Head>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="manifest" href="/site.webmanifest" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
<meta httpEquiv="content-language" content="de" />
</Head>
<Navbar />
<SwitchTransition mode="out-in">
<Transition
timeout={1000}
addEndListener={(node, done) => {
this.handleExit.bind(this);
}}
key={path}
onEnter={this.handleEnter.bind(this)}
onExit={(node, done) => this.handleExit(node, done)}
>
<Component {...pageProps} className="component" />
</Transition>
</SwitchTransition>
<Footer />
<script
async
src="https://www.googletagmanager.com/gtag/js?id=G-504FPVG74X"
></script>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-504FPVG74X');
`,
}}
/>
</>
);
}
}

22
pages/agbs.jsx Normal file
View File

@@ -0,0 +1,22 @@
import React from "react";
import Head from "next/head";
export default function Abgs(props) {
return (
<>
<Head>
<meta name="description" content="Datenschutz" />
<meta name="keywords" content="AGBs, Prothmann, Hans Prothmann GmbH" />
<title>AGBs - Prothmann GmbH</title>
</Head>
<div className="container-fluid products-container navbar-spacing">
<div className="row align-items-center min-height-100">
<div className="col">
<h1 className="text-center">Allgemeine Geschäftsbedingungen</h1>
<p className="text-center">In Bearbeitung</p>
</div>
</div>
</div>
</>
);
}

91
pages/api/contactsend.js Normal file
View File

@@ -0,0 +1,91 @@
import nodemailer from "nodemailer";
const transporter = nodemailer.createTransport({
host: process.env.MAIL_DOMAIN,
port: process.env.MAIL_PORT,
secure: false,
auth: {
user: process.env.MAIL_USER,
pass: process.env.MAIL_PASS,
},
tls: {
rejectUnauthorized: false,
ignoreTLS: false,
requireTLS: true,
},
});
export default async (req, res) => {
const {
firma,
anrede,
titel,
vorname,
nachname,
email,
telefon,
betreff,
nachricht,
} = req.body;
const mailerRes = await mailer({
firma,
anrede,
titel,
vorname,
nachname,
email,
telefon,
betreff,
nachricht,
});
res.send(mailerRes);
};
const mailer = ({
firma,
anrede,
titel,
vorname,
nachname,
email,
telefon,
betreff,
nachricht,
}) => {
let from = "";
let message = "";
if (firma) {
message += `${firma} <br>`;
}
if (anrede) {
message += `${anrede} `;
}
if (titel) {
message += titel + " ";
}
if (vorname) {
message += vorname + " ";
}
from += `${nachname} <${email}>`;
message += `${nachname} <br> ${email} <br><br><h3>${betreff}</h3><p>${nachricht}</p>`;
const mail = {
from,
to: process.env.MAIL_TO,
subject: `${betreff}`,
html: message,
replyTo: email,
};
return new Promise((resolve, reject) => {
transporter.sendMail(mail, (error, info) =>
error ? reject(error) : resolve(info)
);
});
};

71
pages/branchen.jsx Normal file
View File

@@ -0,0 +1,71 @@
import React from "react";
import Head from "next/head";
import Productpage from "../components/productpage.jsx";
const content = {
elektronikbranche: {
title: "Mechanik für die Elektronikbranche",
text: `Viele Elektronikfirmen konzentrieren sich auf ihre Kernkompetenzen und vergeben die Produktion der mechanischen Teile und Gehäuse. Wir als Experten möchten sie bei der Fertigung unterstützen.
Egal wie einfach oder kompliziert ihre Anforderungen an die Mechanik sind, wir können Ihnen helfen. Wir bauen sehr kurzfristig Prototypen, aber freuen uns auch auf ihre Serienproduktion.`,
iconurl: "/icons/laserteile.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/branchen/elektronikbranche.webp",
},
maschinenbau: {
title: "Präzisions-Maschinenbau, Automationstechnik, Robotik",
text: `Im Präzisions-Maschinenbau finden sich neben Frästeilen aus Kostengründen auch immer häufiger Blechteile. Damit sie an der Genauigkeit keine Abstriche machen müssen, nutzen sie unser Know-how.
Wir sind immer Technologieführer und fertigen mit unseren Maschinen hauptsächlich im Feinblechbereich von 0,1 bis 3 mm. Das schont die Achsen unserer Maschinen und erhöht die Präzision.`,
iconurl: "/icons/stanzteile.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/branchen/maschinenbau.webp",
},
medizintechnik: {
title: "Medizintechnik, Messtechnik",
text: `Messtechnik in der Prozesssteuerung oder der Diagnose in der Medizin ist ein Gebiet in dem es auf Qualität ankommt. Diese Qualität können wir mit unseren hochwertigen Bauteilen liefern.
Seit über 40 jahren arbeiten wir für führende Technologieunternehmen und sind natürlich nach den gängigen Normen zertifiziert.`,
iconurl: "/icons/biegeteile.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/branchen/medizintechnik.webp",
},
};
export default function Fertigungsverfahren(props) {
return (
<>
<Head>
<meta
name="description"
content="Wir arbeiten mit Kunden aus den verschiedensten Branchen zusammen. Egal ob Elektronikbranche, Maschinenbau oder Medizintechnik."
/>
<meta
name="keywords"
content="Medizintechnik, Messtechnik, Automationstechnik, Präzisions-Maschinenbau, Robotik, Elektronikbranche"
/>
<title>Branchen - Prothmann GmbH</title>
</Head>
<Productpage
bgurl={content.elektronikbranche.bgurl}
iconurl={content.elektronikbranche.iconurl}
title={content.elektronikbranche.title}
text={content.elektronikbranche.text}
/>
<Productpage
bgurl={content.maschinenbau.bgurl}
iconurl={content.maschinenbau.iconurl}
title={content.maschinenbau.title}
text={content.maschinenbau.text}
reversed
/>
<Productpage
bgurl={content.medizintechnik.bgurl}
iconurl={content.medizintechnik.iconurl}
title={content.medizintechnik.title}
text={content.medizintechnik.text}
/>
</>
);
}

583
pages/datenschutz.jsx Normal file
View File

@@ -0,0 +1,583 @@
import React from "react";
import Head from "next/head";
export default function Datenschutz(props) {
return (
<>
<Head>
<meta name="description" content="Datenschutz" />
<meta
name="keywords"
content="Datenschutz, Prothmann, Hans Prothmann GmbH"
/>
<title>Datenschutz - Prothmann GmbH</title>
</Head>
<div className="container products-container navbar-spacing">
<h1 className="text-center">Datenschutz</h1>
<div className="section-row row">
<div className="section-text-col section-text-col-text-center col">
<p className="text-center">
Verantwortliche Stelle im Sinne der Datenschutzgesetze,
insbesondere der EU-Datenschutzgrundverordnung (DSGVO), ist:
</p>
<p className="text-center">
Hans Prothmann GmbH
<br />
Industriestraße 6<br />
82149 Gröbenzell
</p>
</div>
</div>
<div className="section-row-heading row">
<h4>Ihre Betroffenenrechte</h4>
</div>
<div className="section-row row">
<div className="section-text-col col">
<ul>
<li>
Auskunft über Ihre bei uns gespeicherten Daten und deren
Verarbeitung (Art. 15 DSGVO),
</li>
<li>
Berichtigung unrichtiger personenbezogener Daten (Art. 16
DSGVO),
</li>
<li>
Löschung Ihrer bei uns gespeicherten Daten (Art. 17 DSGVO),
</li>
<li>
Einschränkung der Datenverarbeitung, sofern wir Ihre Daten
aufgrund gesetzlicher Pflichten noch nicht löschen dürfen (Art.
18 DSGVO),
</li>
<li>
Widerspruch gegen die Verarbeitung Ihrer Daten bei uns (Art. 21
DSGVO) und
</li>
<li>
Datenübertragbarkeit, sofern Sie in die Datenverarbeitung
eingewilligt haben oder einen Vertrag mit uns abgeschlossen
haben (Art. 20 DSGVO).
</li>
</ul>
<br />
<p>
Sofern Sie uns eine Einwilligung erteilt haben, können Sie diese
jederzeit mit Wirkung für die Zukunft widerrufen.
<br />
Sie können sich jederzeit mit einer Beschwerde an eine
Aufsichtsbehörde wenden, z. B. an die zuständige Aufsichtsbehörde
des Bundeslands Ihres Wohnsitzes oder an die für uns als
verantwortliche Stelle zuständige Behörde.
<br />
Eine Liste der Aufsichtsbehörden (für den nichtöffentlichen
Bereich) mit Anschrift finden Sie unter:{" "}
<a
href="https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html"
target="_blank"
rel="noopener noreferrer"
>
https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html
</a>
.
</p>
</div>
</div>
<div className="section-row-heading text-center row">
<h4>
Erfassung allgemeiner Informationen beim Besuch unserer Website
</h4>
</div>
<div className="section-row row">
<div className="section-text-col col">
<h5>Art und Zweck der Verarbeitung</h5>
<p>
Wenn Sie auf unsere Website zugreifen, d.h., wenn Sie sich nicht
registrieren oder anderweitig Informationen übermitteln, werden
automatisch Informationen allgemeiner Natur erfasst. Diese
Informationen (Server-Logfiles) beinhalten etwa die Art des
Webbrowsers, das verwendete Betriebssystem, den Domainnamen Ihres
Internet-Service-Providers, Ihre IP-Adresse und ähnliches. Hierbei
handelt es sich ausschließlich um Informationen, welche keine
Rückschlüsse auf Ihre Person zulassen.
</p>
<p>Sie werden insbesondere zu folgenden Zwecken verarbeitet:</p>
<ul>
<li>
Sicherstellung eines problemlosen Verbindungsaufbaus der
Website,
</li>
<li>
Sicherstellung einer reibungslosen Nutzung unserer Website,
</li>
<li>Auswertung der Systemsicherheit und -stabilität sowie</li>
<li>zu weiteren administrativen Zwecken.</li>
</ul>
<br />
<p>
Wir verwenden Ihre Daten nicht, um Rückschlüsse auf Ihre Person zu
ziehen. Informationen dieser Art werden von uns ggfs. statistisch
ausgewertet, um unseren Internetauftritt und die dahinterstehende
Technik zu optimieren.
</p>
<h5>Rechtsgrundlage</h5>
<p>
Die Verarbeitung erfolgt gemäß Art. 6 Abs. 1 lit. f DSGVO auf
Basis unseres berechtigten Interesses an der Verbesserung der
Stabilität und Funktionalität unserer Website.
</p>
<h5>Empfänger</h5>
<p>
Empfänger der Daten sind ggf. technische Dienstleister, die für
den Betrieb und die Wartung unserer Webseite als
Auftragsverarbeiter tätig werden.
</p>
<h5>Speicherdauer</h5>
<p>
Die Daten werden gelöscht, sobald diese für den Zweck der Erhebung
nicht mehr erforderlich sind. Dies ist für die Daten, die der
Bereitstellung der Webseite dienen, grundsätzlich der Fall, wenn
die jeweilige Sitzung beendet ist.
</p>
<h5>Bereitstellung vorgeschrieben oder erforderlich</h5>
<p>
Die Bereitstellung der vorgenannten personenbezogenen Daten ist
weder gesetzlich noch vertraglich vorgeschrieben. Ohne die
IP-Adresse ist jedoch der Dienst und die Funktionsfähigkeit
unserer Website nicht gewährleistet. Zudem können einzelne Dienste
und Services nicht verfügbar oder eingeschränkt sein. Aus diesem
Grund ist ein Widerspruch ausgeschlossen.{" "}
</p>
</div>
</div>
<div className="section-row-heading text-center row">
<h4>Kontaktformular und eAnfrage</h4>
</div>
<div className="section-row row">
<div className="section-text-col col">
<h5>Art und Zweck der Verarbeitung</h5>
<p>
Die von Ihnen eingegebenen Daten werden zum Zweck der
individuellen Kommunikation mit Ihnen gespeichert. Hierfür ist die
Angabe einer validen E-Mail-Adresse sowie Ihres Namens
erforderlich. Diese dient der Zuordnung der Anfrage und der
anschließenden Beantwortung derselben. Die Angabe weiterer Daten
ist optional. Alle Zeichnungen und Konstruktionsdaten werden mit
besonderer Sorgfalt gegen den Zugriff von Dritten geschützt. Wir
benutzen diese Daten nur zur Erstellung von Angeboten und falls
ein Vertrag zustande kommt zur Fertigung. Falls für die Fertigung
der Teile Spezialwerkzeuge nötig sind, werden Zeichnungen und
Daten an ausgesuchte Werkzeugmacher weitergeleitet.
</p>
<h5>Rechtsgrundlage</h5>
<p>
Die Verarbeitung der in das Kontaktformular und eAnfrage Formular
eingegebenen Daten erfolgt auf der Grundlage eines berechtigten
Interesses (Art 6 Abs. 1 lit. f DSGVO).
</p>
<p>
Durch Bereitstellung des Kontaktformulars und des eAnfrage
Formulars möchten wir Ihnen eine unkomplizierte Kontaktaufnahme
ermöglichen. Ihre gemachten Angaben werden zum Zwecke der
Bearbeitung der Anfrage sowie für mögliche Anschlussfragen
gespeichert.
</p>
<p>
Sofern Sie mit uns Kontakt aufnehmen, um ein Angebot zu erfragen,
erfolgt die Verarbeitung der in das Kontaktformular oder aAnfrage
Formular eingegebenen Daten zur Durchführung vorvertraglicher
Maßnahmen (Art 6 Abs. 1 lit. b DSGVO).
</p>
<h5>Empfänger</h5>
<p>Empfänger der Daten sind ggf. Auftragsverarbeiter.</p>
<h5>Speicherdauer</h5>
<p>
Daten werden gelöscht, sobald sie nicht mehr für die Bearbeitung
benötigt werden.
</p>
<p>
Sofern es zu einem Vertragsverhältnis kommt, unterliegen wir den
gesetzlichen Aufbewahrungsfristen nach HGB und löschen Ihre Daten
nach Ablauf dieser Fristen.{" "}
</p>
<h5>Bereitstellung vorgeschrieben oder erforderlich</h5>
<p>
Die Bereitstellung Ihrer personenbezogenen Daten erfolgt
freiwillig. Wir können Ihre Anfrage jedoch nur bearbeiten, sofern
Sie uns Ihren Namen, Ihre E-Mail-Adresse und den Grund der Anfrage
mitteilen.
</p>
</div>
</div>
<div className="section-row-heading text-center row">
<h4>Verwendung von Google Analytics</h4>
</div>
<div className="section-row row">
<div className="section-text-col col">
<h5>Art und Zweck der Verarbeitung</h5>
<p>
Diese Website benutzt Google Analytics, einen Webanalysedienst der
Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043 USA
(nachfolgend: Google). Google Analytics verwendet sog.
Cookies, also Textdateien, die auf Ihrem Computer gespeichert
werden und die eine Analyse der Benutzung der Webseite durch Sie
ermöglichen. Die durch das Cookie erzeugten Informationen über
Ihre Benutzung dieser Webseite werden in der Regel an einen Server
von Google in den USA übertragen und dort gespeichert. Aufgrund
der Aktivierung der IP-Anonymisierung auf diesen Webseiten, wird
Ihre IP-Adresse von Google jedoch innerhalb von Mitgliedstaaten
der Europäischen Union oder in anderen Vertragsstaaten des
Abkommens über den Europäischen Wirtschaftsraum zuvor gekürzt. Nur
in Ausnahmefällen wird die volle IP-Adresse an einen Server von
Google in den USA übertragen und dort gekürzt. Im Auftrag des
Betreibers dieser Website wird Google diese Informationen
benutzen, um Ihre Nutzung der Webseite auszuwerten, um Reports
über die Webseitenaktivitäten zusammenzustellen und um weitere mit
der Websitenutzung und der Internetnutzung verbundene
Dienstleistungen gegenüber dem Webseitenbetreiber zu erbringen.
Die im Rahmen von Google Analytics von Ihrem Browser übermittelte
IP-Adresse wird nicht mit anderen Daten von Google
zusammengeführt.
</p>
<p>
Die Zwecke der Datenverarbeitung liegen in der Auswertung der
Nutzung der Website und in der Zusammenstellung von Reports über
Aktivitäten auf der Website. Auf Grundlage der Nutzung der Website
und des Internets sollen dann weitere verbundene Dienstleistungen
erbracht werden.
</p>
<h5>Rechtsgrundlage</h5>
<p>
Die Verarbeitung der Daten erfolgt auf Grundlage einer
Einwilligung des Nutzers (Art. 6 Abs. 1 lit. a DSGVO).
</p>
<h5>Empfänger</h5>
<p>
Empfänger der Daten ist Google als Auftragsverarbeiter. Hierfür
haben wir mit Google den entsprechenden
Auftragsverarbeitungsvertrag abgeschlossen.
</p>
<h5>Speicherdauer</h5>
<p>
Die Löschung der Daten erfolgt, sobald diese für unsere
Aufzeichnungszwecke nicht mehr erforderlich sind.
</p>
<h5>Drittlandtransfer</h5>
<p>
Google verarbeitet Ihre Daten in den USA und hat sich dem EU_US
Privacy Shield unterworfen{" "}
<a
href="https://www.privacyshield.gov/EU-US-Framework"
target="_blank"
rel="noopener noreferrer"
>
https://www.privacyshield.gov/EU-US-Framework
</a>
. Außerdem haben wir Standarddatenschutzklauseln mit Google für
den Einsatz von Google Analytics abgeschlossen.
</p>
<h5>Bereitstellung vorgeschrieben oder erforderlich</h5>
<p>
Die Bereitstellung Ihrer personenbezogenen Daten erfolgt
freiwillig, allein auf Basis Ihrer Einwilligung. Sofern Sie den
Zugriff unterbinden, kann es hierdurch zu Funktionseinschränkungen
auf der Website kommen.
</p>
<h5>Widerruf der Einwilligung</h5>
<p>
Sie können die Speicherung der Cookies durch eine entsprechende
Einstellung Ihrer Browser-Software verhindern; wir weisen Sie
jedoch darauf hin, dass Sie in diesem Fall gegebenenfalls nicht
sämtliche Funktionen dieser Website vollumfänglich werden nutzen
können. Sie können darüber hinaus die Erfassung der durch das
Cookie erzeugten und auf Ihre Nutzung der Webseite bezogenen Daten
(inkl. Ihrer IP-Adresse) an Google sowie die Verarbeitung dieser
Daten durch Google verhindern, indem sie das unter dem folgenden
Link verfügbare Browser-Plugin herunterladen und installieren:{" "}
<a href="http://tools.google.com/dlpage/gaoptout?hl=de">
Browser Add On zur Deaktivierung von Google Analytics
</a>
.
</p>
<h5>Profiling</h5>
<p>
Mit Hilfe des Tracking-Tools Google Analytics kann das Verhalten
der Besucher der Webseite bewertet und die Interessen analysiert
werden. Hierzu erstellen wir ein pseudonymes Nutzerprofil.
</p>
</div>
</div>
<div className="section-row-heading text-center row">
<h4>Verwendung von Adobe Typekit</h4>
</div>
<div className="section-row row">
<div className="section-text-col col">
<h5>Art und Zweck der Verarbeitung</h5>
<p>
Wir setzen Adobe Typekit zur visuellen Gestaltung unserer Website
ein. Typekit ist ein Dienst der Adobe Systems Software Ireland
Companies (4-6 Riverwalk, Citywest Business Campus, Dublin 24,
Republic of Ireland; nachfolgend Adobe), der uns den Zugriff auf
eine Schriftartenbibliothek gewährt. Zur Einbindung der von uns
benutzten Schriftarten, muss Ihr Browser eine Verbindung zu einem
Server von Adobe in den USA aufbauen und die für unsere Website
benötigte Schriftart herunterladen. Adobe erhält hierdurch die
Information, dass von Ihrer IP-Adresse unsere Website aufgerufen
wurde. Weitere Informationen zu Adobe Typekit finden Sie in den
Datenschutzhinweisen von Adobe, die Sie hier abrufen können:{" "}
<a
href="https://www.adobe.com/de/privacy/policy.html"
target="_blank"
rel="noopener noreferrer"
>
https://www.adobe.com/de/privacy/policy.html
</a>
</p>
<h5>Rechtsgrundlage</h5>
<p>
Rechtsgrundlage für die Einbindung von Adobe Typekit und dem damit
verbundenen Datentransfer zu Adobe ist Ihre Einwilligung (Art. 6
Abs. 1 lit. a DSGVO).
</p>
<h5>Empfänger</h5>
<p>
Der Aufruf von Scriptbibliotheken oder Schriftbibliotheken löst
automatisch eine Verbindung zum Betreiber der Bibliothek aus.
Informationen über die Nutzung Ihrer Daten durch Adobe Typekit Web
Fonts Sie unter{" "}
<a href="https://typekit.com/">https://typekit.com/</a> und in der
Datenschutzerklärung von Adobe Typekit:{" "}
<a
href="https://www.adobe.com/de/privacy/policies/typekit.html"
rel="noopener noreferrer"
>
https://www.adobe.com/de/privacy/policies/typekit.html
</a>
.
</p>
<h5>Speicherdauer</h5>
<p>
Wir erheben keine personenbezogenen Daten durch die Einbindung von
Adobe Typekit Web Fonts.
</p>
<h5>Drittlandtransfer</h5>
<p>
Adobe ist unter dem Privacy-Shield-Abkommen zertifiziert und
bietet hierdurch eine Garantie, das europäische Datenschutzrecht
einzuhalten (
<a href="https://www.privacyshield.gov/participant?id=a2zt0000000TNo9AAG&amp;status=Active">
https://www.privacyshield.gov/participant?id=a2zt0000000TNo9AAG&amp;status=Active
</a>
).
</p>
<h5>Bereitstellung vorgeschrieben oder erforderlich</h5>
<p>
Die Bereitstellung der personenbezogenen Daten ist weder
gesetzlich, noch vertraglich vorgeschrieben. Allerdings kann ohne
die korrekte Darstellung der Inhalte von Standardschriften nicht
ermöglicht werden.
</p>
</div>
</div>
<div className="section-row-heading text-center row">
<h4>Verwendung von Google Maps</h4>
</div>
<div className="section-row row">
<div className="section-text-col col">
<h5>Art und Zweck der Verarbeitung</h5>
<p>
Auf dieser Webseite nutzen wir das Angebot von Google Maps. Google
Maps wird von Google LLC, 1600 Amphitheatre Parkway, Mountain
View, CA 94043, USA (nachfolgend Google) betrieben. Dadurch
können wir Ihnen interaktive Karten direkt in der Webseite
anzeigen und ermöglichen Ihnen die komfortable Nutzung der
Karten-Funktion.
</p>
<p>
Nähere Informationen über die Datenverarbeitung durch Google
können Sie{" "}
<a href="http://www.google.com/privacypolicy.html">
den Google-Datenschutzhinweisen
</a>{" "}
entnehmen. Dort können Sie im Datenschutzcenter auch Ihre
persönlichen Datenschutz-Einstellungen verändern.
</p>
<p>
Ausführliche Anleitungen zur Verwaltung der eigenen Daten im
Zusammenhang mit Google-Produkten
<a href="http://www.dataliberation.org/"> finden Sie hier</a>.
</p>
<h5>Rechtsgrundlage</h5>
<p>
Rechtsgrundlage für die Einbindung von Google Maps und dem damit
verbundenen Datentransfer zu Google ist Ihre Einwilligung (Art. 6
Abs. 1 lit. a DSGVO).
</p>
<h5>Empfänger</h5>
<p>
Durch den Besuch der Webseite erhält Google Informationen, dass
Sie die entsprechende Unterseite unserer Webseite aufgerufen
haben. Dies erfolgt unabhängig davon, ob Google ein Nutzerkonto
bereitstellt, über das Sie eingeloggt sind, oder ob keine
Nutzerkonto besteht. Wenn Sie bei Google eingeloggt sind, werden
Ihre Daten direkt Ihrem Konto zugeordnet.
</p>
<p>
Wenn Sie die Zuordnung in Ihrem Profil bei Google nicht wünschen,
müssen Sie sich vor Aktivierung des Buttons bei Google ausloggen.
Google speichert Ihre Daten als Nutzungsprofile und nutzt sie für
Zwecke der Werbung, Marktforschung und/oder bedarfsgerechter
Gestaltung seiner Webseite. Eine solche Auswertung erfolgt
insbesondere (selbst für nicht eingeloggte Nutzer) zur Erbringung
bedarfsgerechter Werbung und um andere Nutzer des sozialen
Netzwerks über Ihre Aktivitäten auf unserer Webseite zu
informieren. Ihnen steht ein Widerspruchsrecht zu gegen die
Bildung dieser Nutzerprofile, wobei Sie sich zur Ausübung dessen
an Google richten müssen.
</p>
<h5>Speicherdauer</h5>
<p>
Wir erheben keine personenbezogenen Daten, durch die Einbindung
von Google Maps.
</p>
<h5>Drittlandtransfer</h5>
<p>
Google verarbeitet Ihre Daten in den USA und hat sich dem EU_US
Privacy Shield unterworfen{" "}
<a href="https://www.privacyshield.gov/EU-US-Framework">
https://www.privacyshield.gov/EU-US-Framework
</a>
.
</p>
<h5>Widerruf der Einwilligung</h5>
<p>
Wenn Sie nicht möchten, dass Google über unseren Internetauftritt
Daten über Sie erhebt, verarbeitet oder nutzt, können Sie in Ihrem
Browsereinstellungen JavaScript deaktivieren. In diesem Fall
können Sie unsere Webseite jedoch nicht oder nur eingeschränkt
nutzen.
</p>
<h5>Bereitstellung vorgeschrieben oder erforderlich</h5>
<p>
Die Bereitstellung Ihrer personenbezogenen Daten erfolgt
freiwillig, allein auf Basis Ihrer Einwilligung. Sofern Sie den
Zugriff unterbinden, kann es hierdurch zu Funktionseinschränkungen
auf der Website kommen.
</p>
</div>
</div>
<div className="section-row-heading text-center row">
<h4>Google AdWords</h4>
</div>
<div className="section-row row">
<div className="section-text-col col">
<h5>Art und Zweck der Verarbeitung</h5>
<p>
Unsere Webseite nutzt das Google Conversion-Tracking.
Betreibergesellschaft der Dienste von Google AdWords ist die
Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043,
USA. Sind Sie über eine von Google geschaltete Anzeige auf unsere
Webseite gelangt, wird von Google Adwords ein Cookie auf Ihrem
Rechner gesetzt. Das Cookie für Conversion-Tracking wird gesetzt,
wenn ein Nutzer auf eine von Google geschaltete Anzeige klickt.
</p>
<p>
Besucht der Nutzer bestimmte Seiten unserer Website und das Cookie
ist noch nicht abgelaufen, können wir und Google erkennen, dass
der Nutzer auf die Anzeige geklickt hat und zu dieser Seite
weitergeleitet wurde. Jeder Google AdWords-Kunde erhält ein
anderes Cookie. Cookies können somit nicht über die Websites von
AdWords-Kunden nachverfolgt werden. Die mithilfe des
Conversion-Cookies eingeholten Informationen dienen dazu,
Conversion-Statistiken für AdWords-Kunden zu erstellen, die sich
für Conversion-Tracking entschieden haben. Die Kunden erfahren die
Gesamtanzahl der Nutzer, die auf ihre Anzeige geklickt haben und
zu einer mit einem Conversion-Tracking-Tag versehenen Seite
weitergeleitet wurden. Sie erhalten jedoch keine Informationen,
mit denen sich Nutzer persönlich identifizieren lassen.
</p>
<h5>Rechtsgrundlage</h5>
<p>
Rechtsgrundlage für die Einbindung von Google AdWords und dem
damit verbundenen Datentransfer zu Google ist Ihre Einwilligung
(Art. 6 Abs. 1 lit. a DSGVO).
</p>
<h5>Empfänger</h5>
<p>
Bei jedem Besuch unsere Webseite werden personenbezogene Daten,
einschließlich Ihrer IP-Adresse an Google in die USA übertragen.
Diese personenbezogenen Daten werden durch Google gespeichert.
Google gibt diese über das technische Verfahren erhobenen
personenbezogenen Daten unter Umständen an Dritte weiter.
</p>
<p>
Unser Unternehmen enthält keine Informationen von Google, mittels
derer die betroffene Person identifiziert werden könnte.
</p>
<h5>Speicherdauer</h5>
<p>
Diese Cookies verlieren nach 30 Tagen ihre Gültigkeit und dienen
nicht der persönlichen Identifizierung.
</p>
<h5>Drittlandtransfer</h5>
<p>
Google verarbeitet Ihre Daten in den USA und hat sich dem EU_US
Privacy Shield unterworfen{" "}
<a href="https://www.privacyshield.gov/EU-US-Framework">
https://www.privacyshield.gov/EU-US-Framework
</a>
.
</p>
<h5>Widerruf der Einwilligung</h5>
<p>
Möchten Sie nicht am Tracking teilnehmen, können Sie das hierfür
erforderliche Setzen eines Cookies ablehnen etwa per
Browser-Einstellung, die das automatische Setzen von Cookies
generell deaktiviert oder Ihren Browser so einstellen, dass
Cookies von der Domain googleleadservices.com blockiert werden.
</p>
<p>
Bitte beachten Sie, dass Sie die Opt-out-Cookies nicht löschen
dürfen, solange Sie keine Aufzeichnung von Messdaten wünschen.
Haben Sie alle Ihre Cookies im Browser gelöscht, müssen Sie das
jeweilige Opt-out Cookie erneut setzen.
</p>
<h5>Bereitstellung vorgeschrieben oder erforderlich</h5>
<p>
Die Bereitstellung Ihrer personenbezogenen Daten erfolgt
freiwillig, allein auf Basis Ihrer Einwilligung. Sofern Sie den
Zugriff unterbinden, kann es hierdurch zu Funktionseinschränkungen
auf der Website kommen.
</p>
</div>
</div>
<div className="section-row-heading text-center row">
<h4>SSL-Verschlüsselung</h4>
</div>
<div className="section-row row">
<div className="section-text-col col">
<p>
Um die Sicherheit Ihrer Daten bei der Übertragung zu schützen,
verwenden wir dem aktuellen Stand der Technik entsprechende
Verschlüsselungsverfahren (z. B. SSL) über HTTPS.
</p>
</div>
</div>
<div className="section-row-heading text-center row">
<h4>Änderung unserer Datenschutzbestimmungen</h4>
</div>
<div className="section-row row">
<div className="section-text-col col">
<p>
Wir behalten uns vor, diese Datenschutzerklärung anzupassen, damit
sie stets den aktuellen rechtlichen Anforderungen entspricht oder
um Änderungen unserer Leistungen in der Datenschutzerklärung
umzusetzen, z.B. bei der Einführung neuer Services. Für Ihren
erneuten Besuch gilt dann die neue Datenschutzerklärung.
</p>
</div>
</div>
</div>
</>
);
}

222
pages/eanfrage.jsx Normal file
View File

@@ -0,0 +1,222 @@
import React from "react";
import { Formik } from "formik";
import * as Yup from "yup";
import axios from "axios";
import Head from "next/head";
import { EanfrageSchema } from "../components/forms/schemas.jsx";
import IntroForm from "../components/forms/eanfrageforms/introform.jsx";
import ContactPersonForm from "../components/forms/eanfrageforms/contactperson.jsx";
import PartForm from "../components/forms/eanfrageforms/partform.jsx";
import Summary from "../components/forms/eanfrageforms/summary.jsx";
export default class Eanfrage extends React.Component {
constructor(props) {
super(props);
this._renderStepContent = this._renderStepContent.bind(this);
this._handleForward = this._handleForward.bind(this);
this._handleBackwards = this._handleBackwards.bind(this);
this.state = {
rescode: null,
statustext: null,
activeStep: 0,
disabled: false,
};
}
_renderStepContent(
step,
values,
isSubmitting,
handleChange,
handleBlur,
touched,
errors,
setFieldValue
) {
switch (step) {
case 0:
return <IntroForm />;
case 1:
return (
<ContactPersonForm
values={values}
isSubmitting={isSubmitting}
handleChange={handleChange}
handleBlur={handleBlur}
touched={touched}
errors={errors}
disabled={this.state.disabled}
/>
);
case 2:
return (
<PartForm
values={values}
isSubmitting={isSubmitting}
handleChange={handleChange}
handleBlur={handleBlur}
touched={touched}
errors={errors}
disabled={this.state.disabled}
setFieldValue={setFieldValue}
/>
);
case 3:
return <Summary values={values} />;
default:
return <div>Not Found</div>;
}
}
_handleForward() {
this.setState({
activeStep: this.state.activeStep + 1,
});
}
_handleBackwards() {
this.setState({
activeStep: this.state.activeStep - 1,
});
}
render() {
return (
<>
<Head>
<meta
name="description"
content="Die Hans Prothmann GmbH ist Ihr Experte für Blechverarbeitung in München. Professionelles Laserschneiden, Stanzen, Biegen und Gravieren in München."
/>
<meta
name="keywords"
content="Blechverarbeitung München, Blechverarbeitung Gröbenzell, Laserteile, Biegeteile, Stanzteile"
/>
<meta name="robots" content="index, follow" />
<title>eAnfrage - Prothmann GmbH</title>
</Head>
<div className="container background-image landing-img d-flex align-items-center minh-100vh navbar-spacing mb-5">
<div className="col text-center">
<Formik
validationSchema={EanfrageSchema}
initialValues={{
firma: "",
anrede: "",
titel: "",
vorname: "",
nachname: "",
email: "",
telefon: "",
invoiceadress: "",
invoiceplz: "",
diffrentshipping: false,
shippingaddress: "",
shippingplz: "",
parts: [
{
name: "Teststeil",
description: "Dies ist eine total tolle Bschreibung",
material: "Sonstiges",
materialother: "Kupfer Beryllium",
finish: "Sonstiges",
finishother: "DLC",
amount: "1000",
files: [],
engraving: true,
comment:
"Dies hier sind zusätzliche Produktionsanweisungen",
},
],
consent: true,
}}
onSubmit={async (values, errors) => {
console.log(values, errors);
// const data = values;
// try {
// const res = await axios({
// method: "post",
// url: "/api/contactsend",
// headers: {
// "Content-Type": "application/json",
// },
// data,
// });
// this.setState({
// status: "Ihre Nachricht wurde erfolgreich versendet",
// res: res.status,
// });
// } catch (error) {
// this.setState({
// status:
// "Beim versenden ist ein Fehler aufgetreten! Bitte versuchen Sie es in einigen Minuten noch einmal oder schicken Sie und direkt eine e-Mail.",
// res: res.status,
// });
// }
}}
>
{({
values,
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
setFieldValue,
}) => (
<form onSubmit={handleSubmit} className="description">
{this._renderStepContent(
this.state.activeStep,
values,
isSubmitting,
handleChange,
handleBlur,
touched,
errors,
setFieldValue
)}
<div className="d-flex flex-row justify-content-between">
<button
type="button"
className={`btn btn-dark ${
this.state.activeStep <= 0 ? "disabled" : ""
}`}
onClick={this._handleBackwards}
>
Zurück
</button>
{this.state.activeStep !== 3 ? (
<button
type="button"
className={`btn btn-primary`}
onClick={this._handleForward}
>
Weiter
</button>
) : (
<button
type="button"
className={`btn btn-success ${
values.consent === false ? "disabled" : ""
}`}
onClick={handleSubmit}
>
Abschicken
</button>
)}
</div>
</form>
)}
</Formik>
</div>
</div>
</>
);
}
}

View File

@@ -0,0 +1,184 @@
import React from "react";
import Head from "next/head";
import { withRouter } from "next/router";
import Productpage from "../../components/productpage.jsx";
export async function getStaticPaths() {
return {
paths: [
{ params: { index: "laserteile" } },
{ params: { index: "stanzteile" } },
{ params: { index: "biegeteile" } },
{ params: { index: "lasergravur" } },
{ params: { index: "blechkonstruktion" } },
{ params: { index: "baugruppe" } },
{ params: { index: "fügeverfahren" } },
{ params: { index: "entgraten" } },
],
fallback: false, // See the "fallback" section below
};
}
export async function getStaticProps(context) {
let res = {};
switch (context.params.index) {
case "laserteile":
return {
props: {
title: "Laserteile",
text: `Je nach Material kommt bei uns neueste CO2- oder Faserlasertechnik zum Einsatz. Wir schneiden Ihre Werkstoffe mit einer halbfliegenden Optik. Dieses Verfahren erlaubt einen perfekten Schnitt ohne Rückspritzer oder Kratzer. Damit heben wir uns deutlich vom Wettbewerb ab.<br/>
<br/>
Wir schneiden Serienteile sehr wirtschaftlich und mit kurzen Vorlaufzeiten. Bei höheren Stückzahlen können wir unproblematisch aufCNC-Stanz-nibbelTechnik wechseln.<br/>
Komplexe Laserteile mit Umformungen können auch in einem kombinierten Prozess gestanzt und später auf die Lasermaschinen übernommen werden.<br/>
<br/>
Immer komplexere Laserteile im Maschinenbau erfordern immer kleinere Toleranzen. Wir können die branchenüblichen Toleranzen von 0,1 mm deutlich unterschreiten und Teile mit Toleranzen von 0,01 mm in Serie fertigen. Diese Präzision ist sonst nur mit anderen Technologien wie Fräsen möglich. Dafür betreiben wir einen enormen Aufwand um z. B. die Achsen unserer Maschinen immer wieder auf Mikrometer zu kalibrieren.`,
iconurl: "/icons/fertigungsverfahren/laserteile.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/fertigungsverfahren/laserteile.webp",
htitle: "Laserteile - Prothmann GmbH",
hdesc: "Wir fertigen komplexe Laserteile mit Toleranzen von 0,01 mm.",
hkey: "Laserteile, CNC Laser, Laserschneiden",
},
};
case "stanzteile":
return {
props: {
title: "Stanzteile",
text: `Stanz-Nibbel Maschinen sind Teil unserer modernen Fertigungstechnik. Je nach Komplexität des Stanzteiles und der Stückzahl können eine Vielzahl von Umformungen und sogar Abkantungen auf der Stanz-Nibbel Maschine durchgeführt werden. Senkungen, Topfe, Durchzüge,Gewindedüsenund Versteifungsrippen, all diese Fertigungsschritte können an einer Maschine durchgeführt werden. Die meisten Außenkonturen können mit Standardwerkzeugen gestanzt und genibbelt werden. Falls nötig können aber auch Spezialwerkzeuge genutzt werden oder die Kontur auf einerCNC Lasermaschinegeschnitten werden. Unsere kombinierte Software unterstützt den Fertigungsprozess über alle Maschinen hinweg.`,
iconurl: "/icons/fertigungsverfahren/stanzteile.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/fertigungsverfahren/stanzteile.webp",
htitle: "Stanzteile - Prothmann GmbH",
hdesc:
"Wir fertigen komplexe Stanzteile - egal ob 0 Serie oder Massenproduktion.",
hkey: "Stanzteile, CNC Stanzen, Stanzen",
},
};
case "biegeteile":
return {
props: {
title: "Biegeteile",
text: `Das Biegen der Blechplatinen auf Abkantpressen ist die Königsdisziplin in der Blechverarbeitung. Hier macht sich unsere langjährige Erfahrung am stärksten bemerkbar. Die verschiedenen Biegeverfahren, wie Luftbiegung und Prägung, meistern wir hervorragend. Das unterschiedliche Verhalten des Bleches je nach Walzrichtung, Blech-Charge oder Position des Teils im Blech wird bei uns jederzeit mit einbezogen. Nur so können wir Biegeteile von hervorragender Qualität herstellen. Unterstützt werden wir durch die modernsten Simulationsprogramme, in die ständig unsere Erfahrungswerte mit einfließen.
Wir sind auf hochpräzise Biegeteile von 1 mm bis ca. 500 mm spezialisiert. Unser Produktionsspektrum reicht von Gehäuseteilen für die Elektronik, über Getriebeplatten bis hin zu kleinen Federn.
Die Möglichkeiten der Gestaltung sind endlos.
Wir beraten Sie gerne, wenn es um die Machbarkeit von Biegeteilen geht. Dabei können wir bei Bedarf auch Vorschläge zur einfacheren und günstigeren Fertigung machen.`,
iconurl: "/icons/fertigungsverfahren/biegeteile.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/fertigungsverfahren/biegeteile.webp",
htitle: "Biegeteile - Prothmann GmbH",
hdesc:
"Wir sind Marktführer für komplexe Biegeteile. Fordern Sie uns heraus.",
hkey: "Biegeteile, CNC Biegen, Biegen",
},
};
case "lasergravur":
return {
props: {
title: "Lasergravur",
text: `Lasergravuren werden zur Beschriftung von Frontplatten, zur Kennzeichnung mit Seriennummern und für das Aufbringen von QR- und Barcodes genutzt. Wir könnenMaterialienwie z. B. Edelstahl, Messing, Kupfer und eloxiertes Aluminium gravieren. Auch eine Tiefgravierung von 0,1 0,3 mm ist in fast allen Metallen möglich.`,
iconurl: "/icons/fertigungsverfahren/lasergravur.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/fertigungsverfahren/lasergravur.webp",
htitle: "Lasergravieren - Prothmann GmbH",
hdesc:
"Egal ob Seriennummern, Beschriftungen von Frontplattten oder QR-Codes. Wir lasergravieren alle Teile nach Ihren vorgaben.",
hkey: "Lasergravieren, Lasergravur",
},
};
case "blechkonstruktion":
return {
props: {
title: "Blechkonstruktion",
text: `Oft fehlt ein Gehäuse um die Elektronik oder Mechanik herum. Oder es werden Adapterplatten und Winkel benötigt. Hier können wir nach Ihren Vorstellungen eine Konstruktion erstellen!
Wir haben das Know-how um Blechteile zu konstruieren, die später problemlos und damit preiswert zu fertigen sind. Normgerechte Zeichnungen zur späteren Referenz sind dabei für uns selbstverständlich!`,
iconurl: "/icons/fertigungsverfahren/metallkonstruktion.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/fertigungsverfahren/blechkonstruktion.webp",
htitle: "Blechkonstruktion - Prothmann GmbH",
hdesc:
"Wir erstellen für Sie komplexe Blechkontruktionen, wie z.B. Gehäuse für Elektronikteile.",
hkey: "Blechkonstruktion",
},
};
case "baugruppe":
return {
props: {
title: "Baugruppen",
text: `Selbst verständlich können Sie auch kleine Baugruppen bei uns fertigen lassen. Wir können flexibel eine Menge an Montagetätigkeiten übernehmen. Beispiele aus unserem laufenden Betrieb sind:
Schraubverbindungen
Vernieten
Klebungen
Kantenschutz`,
iconurl: "/icons/fertigungsverfahren/baugruppe.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/fertigungsverfahren/baugruppe.webp",
htitle: "Baugruppen - Prothmann GmbH",
hdesc:
"Wir können Baugruppen mit Schraubverbindungen, Vernietungen oder Klebungen herstellen und in einem Stücl zu Ihnen schicken.",
hkey: "Baugruppen",
},
};
case "fügeverfahren":
return {
props: {
title: "Fügeverfahren",
text: `Bei Gehäusen, aber auch bei Funktionsteilen, müssen dauerhafte mechanische Verbindungen hergestellt werden. Routinemäßig werden unsere Teile bei uns im Haus oder bei Partnern mit folgenden Verfahren gefügt:`,
iconurl: "/icons/fertigungsverfahren/fuegeverfahren.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/fertigungsverfahren/fügeverfahren.webp",
htitle: "Fügeverfahren - Prothmann GmbH",
hdesc: "Prothmann GmbH - Ihr Experte für Fügeverfahren München.",
hkey: "Fügeverfahren",
},
};
case "entgraten":
return {
props: {
title: "Entgrattechnik",
text: `Beim Lasern und Stanzen der Blechteile kann an der Unterseite Grat entstehen. Daher werden grundsätzlich werden alle Blechteile entgratet. Dafür stehen folgende Techniken zur Verfügung:
Schleifwalzen
Gleitschleifen / Trowalisieren
Manuelle Entgratung
Je nach Verfahren kann dabei die Oberflächenstruktur geändert werden. Einen Überblick finden Siehier.`,
iconurl: "/icons/fertigungsverfahren/entgraten.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/fertigungsverfahren/entgraten.webp",
htitle: "Entgraten - Prothmann GmbH",
hdesc: "Prothmann GmbH - Ihr Experte für Entgraten München.",
hkey: "Entgraten",
},
};
}
}
class Fertigungsverfahren extends React.Component {
render() {
return (
<>
<Head>
<meta name="description" content={this.props.hdesc} />
<meta name="keywords" content={this.props.hkey} />
<title>{this.props.htitle}</title>
</Head>
<Productpage
bgurl={this.props.bgurl}
iconurl={this.props.iconurl}
title={this.props.title}
text={this.props.text}
/>
</>
);
}
}
export default withRouter(Fertigungsverfahren);

99
pages/impressum.jsx Normal file
View File

@@ -0,0 +1,99 @@
import React from "react";
import GoogleMaps from "../components/GogoleMaps.jsx";
import Head from "next/head";
export default function Impressum(props) {
return (
<>
<Head>
<meta
name="description"
content="Hans Prothmann Gmbh - Industriestr. 6 - 82194 Gröbenzell"
/>
<meta
name="keywords"
content="Impressum, Prothmann, Hans Prothmann GmbH"
/>
<title>Impressum - Prothmann GmbH</title>
</Head>
<div className="container-fluid products-container navbar-spacing">
<div className="row align-items-center min-height-100">
<div
className={`align-self-stretch background-image d-flex flex-column justify-content-center products-img-shadow products-img col-lg-6 p-0`}
>
<GoogleMaps />
</div>
<div
className={`col-lg-6 pl-0 align-self-center p-5 mb-5 h-100 col-lg-6`}
>
<h1 className="mainheading">Impressum</h1>
<div className="description">
<p>
Hans Prothmann GmbH
<br />
Industriestraße 6<br />
82194 Gröbenzell (bei München)
<br />
</p>
<p>
<b>E-Mail</b>{" "}
<a href="mailto:info@prothmann.com">info@prothmann.com</a>
<br />
<b>Telefon</b> <a href="tel:+49814259951">+49 (0) 8142 59951</a>
<br />
<b>Fax</b> <a href="fax:+49814259953">+49 (0) 8142 59953</a>
</p>
<p>
<b>Geschäftsführer</b> Hans & Kolja Prothmann
<br />
<b>Handelsregister</b> HRB München 78953
<br />
<b>USt.-ID</b> DE 128 228 855
</p>
</div>
</div>
</div>
<div className="row">
<div className="col text-center my-5">
<h2>Nützliche Links</h2>
<p>
Unsere Maschinen von Amada
<br />
<a href="http://www.amada.de/" target="_blank">
www.amada.de
</a>
<br />
<br />
Unsere Auszeichnung des percision sheet metal technology fairs
<br />
<a
href="http://www.amada.co.jp/fair/eng/awards/27th/tatech01.html"
target="_blank"
>
www.amada.co.jp
</a>
<br />
<br />
Metallinnung
<br />
<a
href="http://www.fachverband-metall-bayern.de/"
target="_blank"
>
www.fachverband-metall-bayern.de
</a>
<br />
<br />
Unsere Website von CAnetzberger Design
<br />
<a href="https://www.canetzberger.design" target="_blank">
www.canetzberger.design
</a>
</p>
</div>
</div>
</div>
</>
);
}

383
pages/index.js Normal file
View File

@@ -0,0 +1,383 @@
import React from "react";
import Head from "next/head";
import Link from "next/link";
import Image from "next/image";
import { gsap } from "gsap/dist/gsap";
import { ScrollTrigger } from "gsap/dist/ScrollTrigger.js";
import { ReactSVG } from "react-svg";
import ProductContainer from "../components/productscontainer.jsx";
gsap.registerPlugin(ScrollTrigger);
export default class Home extends React.Component {
constructor(props) {
super(props);
this.productsWrapper = React.createRef();
}
componentDidMount() {}
render() {
return (
<>
<Head>
<meta
name="description"
content="Die Hans Prothmann GmbH ist Ihr Experte für Blechverarbeitung in München. Professionelles Laserschneiden, Stanzen, Biegen und Gravieren in München."
/>
<meta
name="keywords"
content="Blechverarbeitung München, Blechverarbeitung Gröbenzell, Laserteile, Biegeteile, Stanzteile"
/>
<meta name="robots" content="index, follow" />
<title> Prothmann - Blechverarbeitung in München </title>
</Head>
<div
className="container-fluid background-image landing-img d-flex align-items-center minh-100vh navbar-spacing"
style={{
backgroundImage:
"url(/background/fertigungsverfahren/laserteile.webp)",
}}
>
<div className="col text-center">
<Image
src="/landinglogo.svg"
className="products-img"
alt="Logo der Hans Prothmann GmbH"
layout="intrinsic"
width={500}
height={500}
/>
</div>
</div>
<div className="container">
<div className="row">
<div className="col mt-5 text-center">
<h1> Ihr Experte für Blechverarbeitung in München </h1>
<p>
Seit 1971 ist die Hans Prothmann GmbH ihr verlässlicher Partner
für Blechverarbeitung in München. Unsere Produktion setzt auf
einen modernen Maschinenpark mit
<Link href="/fertigungsverfahren/laserteile">
<a> CNC Laser-</a>
</Link>
,
<Link href="/fertigungsverfahren/stanzteile">
<a> CNC Stanz-</a>
</Link>
,
<Link href="/fertigungsverfahren/biegeteile">
<a> CNC Biege-</a>
</Link>{" "}
und
<Link href="/fertigungsverfahren/lasergravur">
<a> Gravurtechnik</a>
</Link>
, mit welchem wir anspruchsvolle, qualitativ hochwertige
Bauteile für Sie fertigen - egal ob 0 Serie oder
Massenproduktion.
</p>
<p>
Unsere Stärke liegt vor allem in der Präzision unserer
Fertigungsteile. Branchenübliche Toleranzen von 0, 1 mm können
wir deutlich unterschreiten und Teile mit Toleranzen von 0, 01
mm in Serie fertigen. Um diesen Anforderungen gerecht zu werden,
kalibrieren wir unsere Maschinen regelmäßig auf den Mikrometer
genau - das ist Hightech in Blech.
</p>
</div>
</div>
</div>
<div className="container-fluid mb-5">
<div className="row text-center">
<div className="col-lg-4 col-xs-12 p-0">
<Link href="/fertigungsverfahren/laserteile">
<a>
<div
className="background-image d-flex align-items-center flex-column filter-grey"
style={{
backgroundImage:
"url('/background/fertigungsverfahren/laserteile.webp')",
}}
>
<Image
src="/icons/fertigungsverfahren/laserteile.svg"
alt="Icon einer Lasermaschine zum Herstellen von Laserteile"
className="p-3"
layout="intrinsic"
width={250}
height={250}
/>
<h3 className="text-white"> Laserteile </h3>
</div>
</a>
</Link>
</div>
<div className="col-lg-4 col-xs-12 p-0">
<Link href="/fertigungsverfahren/stanzteile">
<a>
<div
className="background-image d-flex align-items-center flex-column filter-grey"
style={{
backgroundImage:
"url('/background/fertigungsverfahren/stanzteile.webp')",
}}
>
<Image
src="/icons/fertigungsverfahren/stanzteile.svg"
alt="Icon einer Stanzmaschine zum Herstellen von Stanzteile"
className="p-3"
layout="intrinsic"
width={250}
height={250}
/>
<h3 className="text-white"> Stanzteile </h3>
</div>
</a>
</Link>
</div>
<div className="col-lg-4 col-xs-12 p-0">
<Link href="/fertigungsverfahren/biegeteile">
<a>
<div
className="background-image d-flex align-items-center flex-column filter-grey"
style={{
backgroundImage:
"url('/background/fertigungsverfahren/biegeteile.webp')",
}}
>
<Image
src="/icons/fertigungsverfahren/biegeteile.svg"
alt="Icon einer Biegemaschine zum Herstellen von Biegeteilen"
className="p-3"
layout="intrinsic"
width={250}
height={250}
/>
<h3 className="text-white"> Biegeteile </h3>
</div>
</a>
</Link>
</div>
</div>
</div>
<div className="container">
<div className="row">
<div className="col-12 col-lg-8 offset-lg-2 mt-5">
<h2 className="text-center"> Produkte </h2>
<p className="text-center">
Wir verarbeiten alle auf dem Weltmarkt erhältlichen Materialien.
Durch unsere Spezialisierung auf Feinbleche haben wir oft auch
schwierig zu beschaffende Materialien wie z.B. säurebeständige
Edelstähle, Federstahl, Bronze und Messing, sowie Mu-Metal auf
Lager.
</p>
</div>
</div>
<div className="row mb-5">
<ProductContainer
imgurl="/products/elektronikgehaeuse.webp"
imgalt="Elektronikgehäuse aus Blech, Stanzteil, Laserteil"
title="Elektronikgehäuse"
>
<p>
Unsere Elektronikgehäuse werden mit{" "}
<Link href="/fertigungsverfahren/stanzteile">
<a>Stanz-</a>
</Link>{" "}
oder{" "}
<Link href="/fertigungsverfahren/laserteile">
<a>Lasertechnik</a>
</Link>{" "}
aus einer Blechplatine gefertigt. Die endgültige Form bekommen
die Teile nach der Umformung auf unseren{" "}
<Link href="/fertigungsverfahren/biegeteile">
<a>CNC Biegemaschinen</a>
</Link>
.
</p>
</ProductContainer>
<ProductContainer
imgurl="/products/elektronikaufnahme.webp"
imgalt="Edelstahlkörper mit Gewindedüsen, Gewindebolzen, Senkungen und Erdungsfahne"
title="Elektronikaufnahme"
>
<p>
An dem Edelstahlgrundkörper sieht man unser Leistungsspektrum
rund ums Blech. Es sind Gewindedüsen geformt, Gewindebolzen
eingepresst, Senkungen geschnitten und Erdungsfahnen
angeschweißt.
</p>
</ProductContainer>
<ProductContainer
imgurl="/products/chassismesstechnik.webp"
imgalt="Dreieckiges Laserteil mit höchster Präzision"
title="Chassis für Messtechnik"
>
<p>
Spezielle Messtechnik benötigt häufig auch spezielle Lösungen in
der Mechanik. Dieses dreieckige Gehäuse stellt höchste
Anforderungen an die Umform- und Abkanttechnik.
</p>
</ProductContainer>
<ProductContainer
imgurl="/products/teleskopdurchfuehrungen.webp"
imgalt="Teleskopdurchführungen aus Blech mit perfekter Ebenheit"
title="Teleskopdurchführungen"
>
<p>
Bei diesen Biegeteilen liegt die Schwierigkeit in der Ebenheit
der Werkstücke. Die Ebenheit muss selbst nach der
Wärmeeinwirkung beim{" "}
<Link href="/fertigungsverfahren/stanzteile">
<a>Lasern</a>
</Link>{" "}
und nach der Umformung beim{" "}
<Link href="/fertigungsverfahren/biegeteile">
<a>Abkanten</a>
</Link>{" "}
gewährleistet sein.
</p>
</ProductContainer>
<ProductContainer
imgurl="/products/federn.webp"
imgalt="Mit Spezialwerkzeug gefertigte Federn aus exotischen Materialien mit Lasergravur"
title="Federn aus exotischen Materialien"
>
<p>
Wir haben eine große Auswahl an Federstählen auf Lager und
fertigen die Federn mit Spezialwerkzeugen aus eigener
Produktion. Diese Federn aus Kupfer mit{" "}
<Link href="/fertigungsverfahren/lasergravur">
<a>Lasergravur</a>
</Link>{" "}
zeigen die Präzision bei der Fertigung.
</p>
</ProductContainer>
<ProductContainer
imgurl="/products/metallabschirmung.webp"
imgalt="Runde Metallabschirmung aus Blech"
title="MU-Metall Abschirmungen"
>
<p>
Aufgrund unserer langjährigen Erfahrung im audiovisuellen
Anlagenbau sind wir auch Ihr kompetenter Partner in der
Produktion von elektromagnetischen Abschirmungen.
</p>
</ProductContainer>
</div>
</div>
{/* <div className="container-fluid products-container navbar-spacing">
{content.products.map(function (prod) {
return (
<div className="row align-items-center" key={prod.title}>
<div
className={`align-self-stretch background-image d-flex flex-column justify-content-center products-img col-lg-4`}
>
<h3 className="mainheading d-lg-none">{prod.title}</h3>
<div className="icon-size align-items-center bg-light">
<img src={prod.imgurl} />
</div>
</div>
<div
className={`col-lg-6 offset-lg-1 pl-0 align-self-center p-5 mb-5 h-100"`}
>
<div>
<h3 className="mainheading d-none d-lg-block">
{prod.title}
</h3>
<p>{prod.text}</p>
</div>
</div>
</div>
);
})}
</div> */}
{/* <div className="container">
<div className="row">
<div className="col-lg-6">
<div className="sticky_history">
<p>1971</p>
<p>1980</p>
<p>1985</p>
<p>1995</p>
<p>2013</p>
<p>2018</p>
<p>2021</p>
</div>
</div>
<div className="col-12 col-lg-6 history_wrapper mb-5">
<div className="section-wrapper">
<section className="section history">
<h3>Gründung</h3>
<p>
Die Firma Prothmann wurde von Herrn Hans Prothmann als
Personengesellschaft in der Winterstraße in Gröbenzell bei
München gegründet.
</p>
</section>
<section className="section history">
<h3>Umzug #1</h3>
<p>
Umzug zum derzeitigen Standort in die Industriestraße 6 in
Gröbenzell bei München.
</p>
</section>
<section className="section history">
<h3>GmbH</h3>
<p>
1985 wurde die Hans Prothmann GbR in eine GmbH umgewandelt.
</p>
</section>
<section className="section history">
<h3>Digitalisierung</h3>
<p>
Erstmals wurden computergesteuerte Verarbeitungsmaschinen
eingesetzt, welche ständig an die neusten Technologien
angepasst werden. Zudem gelten seither bei uns strenge,
eigens auferlegte Qualitäts-Kriterien, nach welchen wir
unsere Produkte in den modernsten CNC Anlagen herstellen.
Seitdem sind wir eine der führenden Unternehmen, wenn es um
Blechverarbeitung geht.
</p>
</section>
<section className="section history">
<h3>Generationenwechsel</h3>
<p>
Herr Dr. Kolja Prothmann tritt, nachdem er bereits seit
Jahren im Unternehmen tätig ist, in die Geschäftsführung
ein. Herr Hans Prothmann gilt jedoch weiterhin als
Ansprechpartner und unterstützt die Hans Prothmann GmbH mit
seiner jahrzehnte langen Erfahrungen.
</p>
</section>
<section className="section history">
<h3>Lasergravur</h3>
<p>
Dieses Jahr haben wir unser Leistungsspektrum um
Lasergravieren erweitert. Damit können wir eine Vielzahl von
Metallen ganz nach Ihren Vorstellungen Beschriften und
Kennzeichnen.
</p>
</section>
<section className="section history">
<h3>Umzug #2</h3>
<p>
Zum zweiten mal in der Firmengeschichte wechseln wir unseren
Standort. Ab Mitte 2021 finden Sie uns nur wenige Häuser
weiter in der Breslauerstraße 19.
</p>
</section>
</div>
</div>
</div>
</div> */}
</>
);
}
}

281
pages/kontakt.jsx Normal file
View File

@@ -0,0 +1,281 @@
import React from "react";
import { Formik } from "formik";
import axios from "axios";
import Head from "next/head";
import {
TextInput,
TextareaInput,
SelectInput,
} from "../components/forms/formfields.jsx";
import { ContactSchema } from "../components/forms/schemas.jsx";
export default class Kontakt extends React.Component {
constructor(props) {
super(props);
this.state = {
res: null,
status: null,
};
}
render() {
return (
<>
<Head>
<meta
name="description"
content="Sie haben Fragen? Treten Sie einfach mit uns in Kontakt."
/>
<meta name="keywords" content="Prothmann, Kontakt, Kontaktformular" />
<title>Kontakt - Prothmann GmbH</title>
</Head>
<div className="container-fluid products-container navbar-spacing">
<div className="row align-items-center min-height-100">
<div
className={`align-self-stretchd-flex flex-column justify-content-center col-lg-6 p-0 p-5`}
>
<h1 className="mainheading">Kontakt</h1>
<div className="description">
<p>
Nutzen Sie einfach das Kontaktformular auf dieser Seite oder
eine der untern angegebenen Kontaktmöglichkeiten.
<br />
Telefonisch erreichen Sie uns Montag - Freitag von 9:00 Uhr
bis 16:00 Uhr.
<br />
<br />
E-Mail:{" "}
<a href="mailto:info@prothmann.com">info@prothmann.com</a>
<br />
Telefon: <a href="tel:+49814259951">+49 (0) 8142 59951</a>
<br />
Fax: <a href="fax:+49814259953">+49 (0) 8142 59953</a>
<br />
<br />
Anschrift:
<br />
Industriestraße 6<br />
82194 Gröbenzell (bei München)
</p>
</div>
</div>
<div
className={`col-lg-6 pl-0 align-self-center p-5 mb-5 h-100 col-lg-6`}
>
<Formik
validationSchema={ContactSchema}
initialValues={{
firma: "",
anrede: "",
titel: "",
vorname: "",
nachname: "",
email: "",
telefon: "",
betreff: "",
nachricht: "",
}}
onSubmit={async (values) => {
console.log(values);
const data = values;
try {
const res = await axios({
method: "post",
url: "/api/contactsend",
headers: {
"Content-Type": "application/json",
},
data,
});
this.setState({
status: "Ihre Nachricht wurde erfolgreich versendet",
res: res.status,
});
} catch (error) {
this.setState({
status:
"Beim versenden ist ein Fehler aufgetreten! Bitte versuchen Sie es in einigen Minuten noch einmal oder schicken Sie und direkt eine e-Mail.",
res: res.status,
});
}
console.log("State: ", this.state);
}}
>
{({
values,
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
}) => (
<form onSubmit={handleSubmit} className="description">
<div className="row g-2 mb-5">
<div className="col">
<TextInput
isSubmitting={isSubmitting}
rescode={this.state.res}
error={errors.firma}
touched={touched.firma}
placeholder={"Musterfirma"}
onChange={handleChange("firma")}
onBlur={handleBlur("firma")}
value={values.firma}
label="Firma (optional)"
type="text"
/>
</div>
</div>
<div className="row g-2 mb-3">
<div className="col">
<SelectInput
isSubmitting={isSubmitting}
rescode={this.state.res}
error={errors.anrede}
touched={touched.anrede}
placeholder={"Anrede"}
onChange={handleChange("anrede")}
onBlur={handleBlur("anrede")}
value={values.anrede}
label="Anrede"
options={["Herr", "Frau", "Divers"]}
/>
</div>
<div className="col">
<SelectInput
isSubmitting={isSubmitting}
rescode={this.state.res}
error={errors.titel}
touched={touched.titel}
placeholder={"Titel"}
onChange={handleChange("titel")}
onBlur={handleBlur("titel")}
value={values.titel}
label="Titel"
options={["Dr.", "Prof.", "Dipl."]}
/>
</div>
</div>
<div className="row g-2 mb-5">
<div className="col">
<TextInput
isSubmitting={isSubmitting}
rescode={this.state.res}
error={errors.vorname}
touched={touched.vorname}
placeholder={"Max"}
onChange={handleChange("vorname")}
onBlur={handleBlur("vorname")}
value={values.vorname}
label="Vorname (optional)"
type="text"
/>
</div>
<div className="col">
<TextInput
isSubmitting={isSubmitting}
rescode={this.state.res}
error={errors.nachname}
touched={touched.nachname}
placeholder={"Max"}
onChange={handleChange("nachname")}
onBlur={handleBlur("nachname")}
value={values.nachname}
label="Nachname"
type="text"
/>
</div>
</div>
<div className="row g-2 mb-5">
<div className="col">
<TextInput
isSubmitting={isSubmitting}
rescode={this.state.res}
error={errors.email}
touched={touched.email}
placeholder={"max@mustermann.de"}
onChange={handleChange("email")}
onBlur={handleBlur("email")}
value={values.email}
label="eMail"
type="email"
/>
</div>
<div className="col">
<TextInput
isSubmitting={isSubmitting}
rescode={this.state.res}
error={errors.telefon}
touched={touched.telefon}
placeholder={"max@mustermann.de"}
onChange={handleChange("telefon")}
onBlur={handleBlur("telefon")}
value={values.telefon}
label="Telefon (optional)"
type="text"
/>
</div>
</div>
<div className="row g-2 mb-3">
<div className="col-12">
<TextInput
isSubmitting={isSubmitting}
rescode={this.state.res}
error={errors.betreff}
touched={touched.betreff}
placeholder={"Betreff"}
onChange={handleChange("betreff")}
onBlur={handleBlur("betreff")}
value={values.betreff}
label="Betreff"
type="text"
/>
</div>
<div className="col-12">
<TextareaInput
isSubmitting={isSubmitting}
rescode={this.state.res}
error={errors.nachricht}
touched={touched.nachricht}
placeholder={"Nachricht"}
onChange={handleChange("nachricht")}
onBlur={handleBlur("nachricht")}
value={values.nachricht}
label="Nachricht"
/>
</div>
</div>
<div className="row g-2 mb-3">
<div className="col">
<p>{this.state.status}</p>
{!isSubmitting && this.state.res != 200 && (
<button className="btn btn-dark" type="submit">
Abschicken
</button>
)}
{isSubmitting && (
<div className="spinner-border" role="status">
<span className="visually-hidden">Sende...</span>
</div>
)}
</div>
</div>
</form>
)}
</Formik>
</div>
</div>
</div>
</>
);
}
}

215
pages/materialien.jsx Normal file
View File

@@ -0,0 +1,215 @@
import React, { useEffect } from "react";
import Head from "next/head";
import Productpage from "../components/productpage.jsx";
const content = {
stahl: {
title: "Materialien",
text: ` Wir fertigen Blechteile aus verschiedensten auf dem Weltmarkt
erhältlichen Materialien. Zu unserem Standardrepertoire gehören
natürlich schiedenste Edelstähle, welche wir meist auch auf Vorrat haben.`,
iconurl: "/icons/laserteile.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/materialien/stahl.webp",
},
aluminium: {
title: "Aluminium",
text: `Aluminium bietet sich an, wenn Gewicht eine Rolle spielt, jedoch trotzdem eine gewisse strukkturelle Stabilität aufweisen muss.`,
iconurl: "/icons/laserteile.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/materialien/aluminium.webp",
},
sonstiges: {
title: "Sonstiges",
text: `Falls Sie besondere
Anforderungen haben, fertigen wir Ihre Teile gerne aus exotischen
Materialien, wie z.B. Kuper-Beryllium, Mesing oder auch Gold - Für uns ist kein Material zu schwierig.`,
iconurl: "/icons/laserteile.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/materialien/sonstiges.webp",
},
};
function ContentSteel() {
return (
<>
<table className="table mt-5">
<thead className="table-secondary">
<tr>
<th>Stähle</th>
<th>Stärke min. (mm)</th>
<th>Stärke max. (mm)</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1.4301 V2A Feinstblech</th>
<td>0,1</td>
<td>0,4</td>
</tr>
<tr>
<th scope="row">1.4301 V2A Dünnblech</th>
<td>0,5</td>
<td>1,5</td>
</tr>
<tr>
<th scope="row">1.4301 V2A Blech</th>
<td>1,5</td>
<td>5,0</td>
</tr>
<tr>
<th scope="row">1.4310 Federstahl</th>
<td>0,1</td>
<td>2,0</td>
</tr>
<tr>
<th scope="row">1.4404 V4A</th>
<td></td>
<td></td>
</tr>
<tr>
<th scope="row">1.4751 V4A</th>
<td></td>
<td></td>
</tr>
<tr>
<th scope="row">1.4016 Blech</th>
<td>0,5</td>
<td>3,0</td>
</tr>
<tr>
<th scope="row">DC01 Stahl</th>
<td></td>
<td></td>
</tr>
<tr>
<th scope="row">St37 Stahl</th>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</>
);
}
function ContenAluminum() {
return (
<>
<table className="table mt-5">
<thead className="table-secondary">
<tr>
<th>Aluminium</th>
<th>Stärke min. (mm)</th>
<th>Stärke max. (mm)</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">AlMg3</th>
<td>0,5</td>
<td>5,0</td>
</tr>
<tr>
<th scope="row">AlSi</th>
<td>0,5</td>
<td>5,0</td>
</tr>
<tr>
<th scope="row">Al99</th>
<td>0,5</td>
<td>5,0</td>
</tr>
</tbody>
</table>
</>
);
}
function ContenOther() {
return (
<>
<table className="table mt-5">
<thead className="table-secondary">
<tr>
<th>Sonstiges</th>
<th>Stärke min. (mm)</th>
<th>Stärke max. (mm)</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Kupfer</th>
<td></td>
<td></td>
</tr>
<tr>
<th scope="row">Titan</th>
<td></td>
<td></td>
</tr>
<tr>
<th scope="row">Messing</th>
<td></td>
<td></td>
</tr>
<tr>
<th scope="row">CuBe Bronze</th>
<td>0,1</td>
<td>1,0</td>
</tr>
<tr>
<th scope="row">Mu-Metall</th>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</>
);
}
export default function Materialien(props) {
return (
<>
<Head>
<meta
name="description"
content="Wir fertigen Blechteile aus verschiedensten auf dem Weltmarkt erhältlichen Materialien. Fordern Sie uns heraus!"
/>
<meta name="keywords" content="Blech, Edelstahl, Aluminium, Kupfer" />
<title>Materialien - Prothmann GmbH</title>
</Head>
<Productpage
bgurl={content.stahl.bgurl}
iconurl={content.stahl.iconurl}
title={content.stahl.title}
text={content.stahl.text}
addtext={<ContentSteel />}
/>
<Productpage
bgurl={content.aluminium.bgurl}
iconurl={content.aluminium.iconurl}
title={content.aluminium.title}
text={content.aluminium.text}
addtext={<ContenAluminum />}
reversed
/>
<Productpage
bgurl={content.sonstiges.bgurl}
iconurl={content.sonstiges.iconurl}
title={content.sonstiges.title}
text={content.sonstiges.text}
addtext={<ContenOther />}
/>
</>
);
}

74
pages/qualitaet.jsx Normal file
View File

@@ -0,0 +1,74 @@
import React from "react";
import Head from "next/head";
import Productpage from "../components/productpage.jsx";
const content = {
auszeichnungen: {
title: "Auszeichnungen",
text: `The Precision Sheet Metal Technology Fair ist ein seit 1989 existenter Wettbewerb für AMADA Kunden, um Blechteile mit besonderer Qualität und Innovation auszuzeichnen.`,
iconurl: "/icons/qualitaet/auszeichnungen.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/qualitaet/auszeichnungen.webp",
},
messtechnik: {
title: "Messtechnik",
text: `Grundsätzlich werden alle Teile über den gesamten Fertigungsprozess maßlich überwacht. Auf Wunsch erstellen wir ein Erstmusterprüfprotokoll.
Wir verwenden kalibrierte Messmittel und folgende Messmaschinen:
Mauser Capax 2 digitaler Höhenmesser
Messmikroskop Digiscope`,
iconurl: "/icons/qualitaet/messtechnik.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/qualitaet/messtechnik.webp",
},
iso: {
title: "ISO Zertifizierung",
text: `Wir leben unseren ISO 9001:2008 Prozess! Schon lange bevor der Betrieb zertifiziert wurde haben wir nach strikten Auflagen gearbeitet.
Diese Philosophie merkt man bei jeder Bestellung, nie eine Reklamation!
Natürlich fertigen wir auf Wunsch auch Erstmusterprüfprotokolle für unsere Teile an.`,
iconurl: "/icons/qualitaet/iso.svg",
iconalt: "Lasermachine beim herstellen von Laserteilen",
bgurl: "/background/qualitaet/iso-zertifizierung.webp",
},
};
export default function Fertigungsverfahren() {
return (
<>
<Head>
<meta
name="description"
content="Mit unseren hochpräzisen Messtechniken garantieren wir perfekte Ergebnisse."
/>
<meta
name="keywords"
content="Precision Sheet Metal Technology Fair, Erstmusterprüfprotokoll, ISO Zertifizierung"
/>
<title>Qualität - Prothmann GmbH</title>
</Head>
<Productpage
bgurl={content.auszeichnungen.bgurl}
iconurl={content.auszeichnungen.iconurl}
title={content.auszeichnungen.title}
text={content.auszeichnungen.text}
/>
<Productpage
bgurl={content.messtechnik.bgurl}
iconurl={content.messtechnik.iconurl}
title={content.messtechnik.title}
text={content.messtechnik.text}
reversed
/>
<Productpage
bgurl={content.iso.bgurl}
iconurl={content.iso.iconurl}
title={content.iso.title}
text={content.iso.text}
/>
</>
);
}

View File

@@ -0,0 +1,28 @@
module.exports = {
plugins: [
"postcss-flexbugs-fixes",
[
"postcss-preset-env",
{
autoprefixer: {
flexbox: "no-2009",
},
stage: 3,
features: {
"custom-properties": false,
},
},
],
[
"@fullhuman/postcss-purgecss",
{
content: [
"./pages/**/*.{js,jsx,ts,tsx}",
"./components/**/*.{js,jsx,ts,tsx}",
],
defaultExtractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],
safelist: ["html", "body"],
},
],
],
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Some files were not shown because too many files have changed in this diff Show More