Linted the whole project with eslint #3

Merged
Skydust merged 1 commits from f/linting into master 2023-08-31 17:44:10 +00:00
29 changed files with 2931 additions and 1686 deletions
Showing only changes of commit 7be98e1793 - Show all commits

503
.eslintrc Normal file
View File

@@ -0,0 +1,503 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"jsx": true,
"useJSXTextNode": true
},
"extends": [
"plugin:@typescript-eslint/recommended"
],
"plugins": ["@typescript-eslint", "react-hooks", "react"],
"rules": {
"@typescript-eslint/no-inferrable-types": 0,
"@typescript-eslint/no-empty-function": 0,
"@typescript-eslint/no-var-requires": 0,
"@typescript-eslint/no-shadow": ["error"],
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/explicit-module-boundary-types": 0,
"@typescript-eslint/no-unused-vars": 0,
//
//Possible Errors
//
// The following rules point out areas where you might have made mistakes.
//
"comma-dangle": 2,
// disallow or enforce trailing commas
"no-cond-assign": 2,
// disallow assignment in conditional expressions
"no-console": [
"warn",
{
"allow": [
"warn",
"error"
]
}
],
// disallow use of console (off by default in the node environment)
"no-constant-condition": 2,
// disallow use of constant expressions in conditions
"no-control-regex": 2,
// disallow control characters in regular expressions
"no-debugger": 2,
// disallow use of debugger
"no-dupe-args": 2,
// disallow duplicate arguments in functions
"no-dupe-keys": 2,
// disallow duplicate keys when creating object literals
"no-duplicate-case": 2,
// disallow a duplicate case label.
"no-empty": 2,
// disallow empty statements
"no-empty-character-class": 2,
// disallow the use of empty character classes in regular expressions
"no-ex-assign": 2,
// disallow assigning to the exception in a catch block
"no-extra-boolean-cast": 2,
// disallow double-negation boolean casts in a boolean context
"no-extra-parens": 0,
// disallow unnecessary parentheses (off by default)
"no-extra-semi": 2,
// disallow unnecessary semicolons
"no-func-assign": 2,
// disallow overwriting functions written as function declarations
"no-inner-declarations": 2,
// disallow function or variable declarations in nested blocks
"no-invalid-regexp": 2,
// disallow invalid regular expression strings in the RegExp constructor
"no-irregular-whitespace": 2,
// disallow irregular whitespace outside of strings and comments
"no-negated-in-lhs": 2,
// disallow negation of the left operand of an in expression
"no-obj-calls": 2,
// disallow the use of object properties of the global object (Math and JSON) as functions
"no-regex-spaces": 2,
// disallow multiple spaces in a regular expression literal
"no-sparse-arrays": 2,
// disallow sparse arrays
"no-unreachable": 2,
// disallow unreachable statements after a return, throw, continue, or break statement
"use-isnan": 2,
// disallow comparisons with the value NaN
"valid-jsdoc": 2,
// Ensure JSDoc comments are valid (off by default)
"valid-typeof": 2,
// Ensure that the results of typeof are compared against a valid string
//
// Best Practices
//
// These are rules designed to prevent you from making mistakes.
// They either prescribe a better way of doing something or help you avoid footguns.
//
"prefer-arrow-callback": 2,
"block-scoped-var": 0,
// treat var statements as if they were block scoped (off by default). 0: deep destructuring is not compatible https://github.com/eslint/eslint/issues/1863
"complexity": 0,
// specify the maximum cyclomatic complexity allowed in a program (off by default)
"consistent-return": 2,
// require return statements to either always or never specify values
"curly": 2,
// specify curly brace conventions for all control statements
"default-case": 2,
// require default case in switch statements (off by default)
"dot-notation": 2,
// encourages use of dot notation whenever possible
"eqeqeq": 0,
// require the use of === and !==
"guard-for-in": 2,
// make sure for-in loops have an if statement (off by default)
"no-alert": 2,
// disallow the use of alert, confirm, and prompt
"no-caller": 2,
// disallow use of arguments.caller or arguments.callee
"no-div-regex": 2,
// disallow division operators explicitly at beginning of regular expression (off by default)
"no-else-return": 2,
// disallow else after a return in an if (off by default)
"no-eq-null": 2,
// disallow comparisons to null without a type-checking operator (off by default)
"no-eval": 1,
// disallow use of eval()
"no-extend-native": 2,
// disallow adding to native types
"no-extra-bind": 2,
// disallow unnecessary function binding
"no-fallthrough": 2,
// disallow fallthrough of case statements
"no-floating-decimal": 2,
// disallow the use of leading or trailing decimal points in numeric literals (off by default)
"no-implied-eval": 2,
// disallow use of eval()-like methods
"no-iterator": 2,
// disallow usage of __iterator__ property
"no-labels": 2,
// disallow use of labeled statements
"no-lone-blocks": 2,
// disallow unnecessary nested blocks
"no-loop-func": 2,
// disallow creation of functions within loops
"no-multi-spaces": 2,
// disallow use of multiple spaces
"no-multi-str": 2,
// disallow use of multiline strings
"no-native-reassign": 2,
// disallow reassignments of native objects
"no-new": 0,
// disallow use of new operator when not part of the assignment or comparison
"no-new-func": 2,
// disallow use of new operator for Function object
"no-new-wrappers": 2,
// disallows creating new instances of String,Number, and Boolean
"no-octal": 2,
// disallow use of octal literals
"no-octal-escape": 2,
// disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251";
"no-param-reassign": 2,
// disallow reassignment of function parameters (off by default)
"no-process-env": 0,
// disallow use of import.meta.env (off by default)
"no-proto": 2,
// disallow usage of __proto__ property
"no-redeclare": 2,
// disallow declaring the same variable more then once
"no-return-assign": 0,
// disallow use of assignment in return statement
"no-script-url": 2,
// disallow use of javascript: urls.
"no-self-compare": 2,
// disallow comparisons where both sides are exactly the same (off by default)
"no-sequences": 2,
// disallow use of comma operator
"no-throw-literal": 2,
// restrict what can be thrown as an exception (off by default)
"no-unused-expressions": 0,
// disallow usage of expressions in statement position
"no-void": 2,
// disallow use of void operator (off by default)
"no-warning-comments": [
0,
{
"terms": [
"todo",
"fixme"
],
"location": "start"
}
],
// disallow usage of configurable warning terms in comments": 2, // e.g. TODO or FIXME (off by default)
"no-with": 2,
// disallow use of the with statement
"radix": 0,
// require use of the second argument for parseInt() (off by default)
"vars-on-top": 2,
// requires to declare all vars on top of their containing scope (off by default)
"wrap-iife": 2,
// require immediate function invocation to be wrapped in parentheses (off by default)
"yoda": 2,
// require or disallow Yoda conditions
//
// Strict Mode
//
// These rules relate to using strict mode.
//
"strict": 0,
// controls location of Use Strict Directives. 0: required by `babel-eslint`
//
// Variables
//
// These rules have to do with variable declarations.
//
"no-catch-shadow": 2,
// disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment)
"no-delete-var": 2,
// disallow deletion of variables
"no-label-var": 2,
// disallow labels that share a name with a variable
"no-shadow": 2,
// disallow declaration of variables already declared in the outer scope
"no-shadow-restricted-names": 2,
// disallow shadowing of names such as arguments
"no-undef-init": 2,
// disallow use of undefined when initializing variables
"no-undefined": 0,
// disallow use of undefined variable (off by default)
"no-unused-vars": 0,
// disallow declaration of variables that are not used in the code
"no-use-before-define": 0,
// disallow use of variables before they are defined
"init-declarations": 2,
//
// Stylistic Issues
//
// These rules are purely matters of style and are quite subjective.
//
"indent": [
2,
4,
{
"SwitchCase": 1
}
],
// this option sets a specific tab width for your code (off by default)
"brace-style": 0,
// enforce one true brace style (off by default)
"camelcase": 0,
// require camel case names
"comma-spacing": [
1,
{
"before": false,
"after": true
}
],
// enforce spacing before and after comma
"comma-style": [
1,
"last"
],
// enforce one true comma style (off by default)
"consistent-this": [
1,
"_this"
],
// enforces consistent naming when capturing the current execution context (off by default)
"eol-last": 0,
// enforce newline at the end of file, with no multiple empty lines
"func-names": 0,
// require function expressions to have a name (off by default)
"func-style": 0,
// enforces use of function declarations or expressions (off by default)
"key-spacing": [
1,
{
"beforeColon": false,
"afterColon": true
}
],
// enforces spacing between keys and values in object literal properties
"max-nested-callbacks": [ 1, 5 ],
// specify the maximum depth callbacks can be nested (off by default)
"new-cap": [
1,
{
"newIsCap": true,
"capIsNew": false
}
],
// require a capital letter for constructors
"new-parens": 1,
// disallow the omission of parentheses when invoking a constructor with no arguments
"newline-after-var": 0,
// allow/disallow an empty newline after var statement (off by default)
"no-array-constructor": 1,
// disallow use of the Array constructor
"no-inline-comments": 0,
// disallow comments inline after code (off by default)
"no-lonely-if": 1,
// disallow if as the only statement in an else block (off by default)
"no-mixed-spaces-and-tabs": 1,
// disallow mixed spaces and tabs for indentation
"no-multiple-empty-lines": [
1,
{
"max": 2
}
],
// disallow multiple empty lines (off by default)
"no-nested-ternary": 2,
// disallow nested ternary expressions (off by default)
"no-new-object": 1,
// disallow use of the Object constructor
"no-spaced-func": 1,
// disallow space between function identifier and application
"no-ternary": 0,
// disallow the use of ternary operators (off by default)
"no-unneeded-ternary": 2,
"no-trailing-spaces": 2,
// disallow trailing whitespace at the end of lines
"no-underscore-dangle": 0,
// disallow dangling underscores in identifiers
"prefer-reflect": 0,
"one-var": [
0,
"never"
],
// allow just one var statement per function (off by default)
"operator-assignment": [
1,
"never"
],
// require assignment operator shorthand where possible or prohibit it entirely (off by default)
"padded-blocks": [
2,
"never"
],
// enforce padding within blocks (off by default)
"quote-props": [
1,
"as-needed"
],
// require quotes around object literal property names (off by default)
"quotes": [
2,
"double"
],
// specify whether double or single quotes should be used
"semi": [
2,
"always"
],
// require or disallow use of semicolons instead of ASI
"semi-spacing": [
1,
{
"before": false,
"after": true
}
],
// enforce spacing before and after semicolons
"sort-vars": 0,
// sort variables within the same declaration block (off by default)
"sort-imports": 0,
"keyword-spacing": [
1
],
// require a space after certain keywords (off by default)
"space-before-blocks": [
1,
"always"
],
// require or disallow space before blocks (off by default)
"space-before-function-paren": [
0
],
// require or disallow space before function opening parenthesis (off by default)
"object-curly-spacing": [
2,
"always"
],
"template-curly-spacing": [
"error",
"always"
],
"array-bracket-spacing": [
0
],
"space-in-parens": [
1,
"never"
],
// require or disallow spaces inside parentheses (off by default)
"space-infix-ops": 0,
// require spaces around operators
"space-unary-ops": [
1,
{
"words": true,
"nonwords": false
}
],
// Require or disallow spaces before/after unary operators (words on by default, nonwords off by default)
"spaced-comment": [
1,
"always"
],
// require or disallow a space immediately following the // in a line comment (off by default)
"wrap-regex": 0,
// require regex literals to be wrapped in parentheses (off by default)
//
// ECMAScript 6
//
// These rules are only relevant to ES6 environments and are off by default.
//
"no-var": 2,
// require let or const instead of var (off by default)
"generator-star-spacing": [
2,
"before"
],
// enforce the spacing around the * in generator functions (off by default)
//
// Legacy
//
// The following rules are included for compatibility with JSHint and JSLint.
// While the names of the rules may not match up with the JSHint/JSLint counterpart,
// the functionality is the same.
//
"max-depth": [
2,
3
],
// specify the maximum depth that blocks can be nested (off by default)
"max-len": [
0,
180,
2
],
// specify the maximum length of a line in your program (off by default)
"max-params": [
0
],
// limits the number of parameters that can be used in the function declaration. (off by default)
"max-statements": 0,
// specify the maximum number of statement allowed in a function (off by default)
"no-bitwise": 0,
// disallow use of bitwise operators (off by default)
"no-plusplus": 0,
// disallow use of unary operators, ++ and -- (off by default)
//
// eslint-plugin-react
//
// React specific linting rules for ESLint
//
"react/display-name": 0,
// Prevent missing displayName in a React component definition
"jsx-quotes": [
2,
"prefer-double"
],
"react/jsx-curly-spacing": [
2,
{
"when": "always",
"allowMultiline": false,
"children": true
}
],
// Enforce quote style for JSX attributes
"react/jsx-no-undef": 2,
// Disallow undeclared variables in JSX
"react/jsx-sort-props": 0,
// Enforce props alphabetical sorting
"react/sort-comp": [
2,
{
"order": [
"constructor",
"lifecycle",
"everything-else",
"render"
]
}
],
"react/jsx-uses-react": 2,
// Prevent React to be incorrectly marked as unused
"react/jsx-uses-vars": 2,
// Prevent variables used in JSX to be incorrectly marked as unused
//"react/no-did-mount-set-state": 2,
"react/no-did-mount-set-state": 0,
// Prevent usage of setState in componentDidMount
"react/no-did-update-set-state": 1,
// Prevent usage of setState in componentDidUpdate
"react/no-multi-comp": 0,
// Prevent multiple component definition per file
"react/no-unknown-property": 2,
// Prevent usage of unknown DOM property
"react/self-closing-comp": 2,
// Prevent extra closing tags for components without children
"react/jsx-wrap-multilines": 2,
// Prevent missing parentheses around multilines JSX
"react/forbid-prop-types": 0,
"react-hooks/exhaustive-deps": 0
}
}

View File

@@ -10,7 +10,7 @@ export const Blocks = (props: Omit<Page, "id" | "_sys" | "_values">) => {
return (
<>
{ props.blocks
? props.blocks.map(function (block, i) {
? props.blocks.map((block, i) => {
return (
<div key={ i } data-tina-field={ tinaField(block) }>
<Block { ...block } />

View File

@@ -20,17 +20,17 @@ export const carouselBlockSchema: Template = {
label: "Carousel",
ui: {
previewSrc: "/blocks/features.png",
defaultItem: [defaultCarousel, defaultCarousel, defaultCarousel],
defaultItem: [defaultCarousel, defaultCarousel, defaultCarousel]
},
fields: [
{
type: "image",
label: "Images du carousel",
name: "images",
list: true,
list: true
},
{
...anchoringSchema
}
],
]
};

View File

@@ -11,7 +11,7 @@ export const Content = ({ data }: { data: PageBlocksContent }) => {
<Section color={ data.color }>
<Container
className={ `prose prose-lg ${
data.color === "primary" ? `prose-primary` : `dark:prose-dark`
data.color === "primary" ? "prose-primary" : "dark:prose-dark"
}` }
data-tina-field={ tinaField(data, "body") }
size="large"
@@ -29,14 +29,14 @@ export const contentBlockSchema: Template = {
ui: {
previewSrc: "/blocks/content.png",
defaultItem: {
body: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.",
},
body: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede."
}
},
fields: [
{
type: "rich-text",
label: "Body",
name: "body",
name: "body"
},
{
type: "string",
@@ -45,8 +45,8 @@ export const contentBlockSchema: Template = {
options: [
{ label: "Default", value: "default" },
{ label: "Tint", value: "tint" },
{ label: "Primary", value: "primary" },
],
},
],
{ label: "Primary", value: "primary" }
]
}
]
};

View File

@@ -4,14 +4,14 @@ import { Icon } from "../util/icon";
import { iconSchema } from "../util/icon";
import {
PageBlocksFeatures,
PageBlocksFeaturesItems,
PageBlocksFeaturesItems
} from "../../tina/__generated__/types";
import { tinaField } from "tinacms/dist/react";
import { Template } from "tinacms";
export const Feature = ({
featuresColor,
data,
data
}: {
featuresColor: string;
data: PageBlocksFeaturesItems;
@@ -53,11 +53,11 @@ export const Features = ({ data }: { data: PageBlocksFeatures }) => {
return (
<Section color={ data.color }>
<Container
className={`flex flex-wrap gap-x-10 gap-y-8 text-left`}
className={ "flex flex-wrap gap-x-10 gap-y-8 text-left" }
size="large"
>
{ data.items &&
data.items.map(function (block, i) {
data.items.map((block, i) => {
return <Feature featuresColor={ data.color } key={ i } data={ block } />;
}) }
</Container>
@@ -71,8 +71,8 @@ const defaultFeature = {
icon: {
color: "",
style: "float",
name: "",
},
name: ""
}
};
export const featureBlockSchema: Template = {
@@ -81,8 +81,8 @@ export const featureBlockSchema: Template = {
ui: {
previewSrc: "/blocks/features.png",
defaultItem: {
items: [defaultFeature, defaultFeature, defaultFeature],
},
items: [defaultFeature, defaultFeature, defaultFeature]
}
},
fields: [
{
@@ -93,29 +93,29 @@ export const featureBlockSchema: Template = {
ui: {
itemProps: (item) => {
return {
label: item?.title,
label: item?.title
};
},
defaultItem: {
...defaultFeature,
},
...defaultFeature
}
},
fields: [
iconSchema,
{
type: "string",
label: "Title",
name: "title",
name: "title"
},
{
type: "string",
label: "Text",
name: "text",
ui: {
component: "textarea",
},
},
],
component: "textarea"
}
}
]
},
{
type: "string",
@@ -124,8 +124,8 @@ export const featureBlockSchema: Template = {
options: [
{ label: "Default", value: "default" },
{ label: "Tint", value: "tint" },
{ label: "Primary", value: "primary" },
],
},
],
{ label: "Primary", value: "primary" }
]
}
]
};

View File

@@ -16,7 +16,7 @@ export const Hero = ({ data }: { data: PageBlocksHero }) => {
pink: "from-pink-400 to-pink-600",
purple: "from-purple-400 to-purple-600",
orange: "from-orange-300 to-orange-600",
yellow: "from-yellow-400 to-yellow-600",
yellow: "from-yellow-400 to-yellow-600"
};
return (
@@ -32,13 +32,13 @@ export const Hero = ({ data }: { data: PageBlocksHero }) => {
className="relative inline-block px-3 py-1 mb-8 text-md font-bold tracking-wide title-font z-20"
>
{ data.tagline }
<span className="absolute w-full h-full left-0 top-0 rounded-full -z-1 bg-current opacity-7"></span>
<span className="absolute w-full h-full left-0 top-0 rounded-full -z-1 bg-current opacity-7" />
</h2>
) }
{ data.headline && (
<h3
data-tina-field={ tinaField(data, "headline") }
className={`w-full relative mb-10 text-5xl font-extrabold tracking-normal leading-tight title-font`}
className={ "w-full relative mb-10 text-5xl font-extrabold tracking-normal leading-tight title-font" }
>
<span
className={ "bg-clip-text text-transparent bg-gradient-to-r from-white to-gray-100" }
@@ -93,24 +93,24 @@ export const heroBlockSchema: Template = {
defaultItem: {
tagline: "Here's some text above the other text",
headline: "This Big Text is Totally Awesome",
text: "Phasellus scelerisque, libero eu finibus rutrum, risus risus accumsan libero, nec molestie urna dui a leo.",
},
text: "Phasellus scelerisque, libero eu finibus rutrum, risus risus accumsan libero, nec molestie urna dui a leo."
}
},
fields: [
{
type: "string",
label: "Tagline",
name: "tagline",
name: "tagline"
},
{
type: "string",
label: "Headline",
name: "headline",
name: "headline"
},
{
label: "Text",
name: "text",
type: "rich-text",
type: "rich-text"
},
{
label: "Actions",
@@ -122,15 +122,15 @@ export const heroBlockSchema: Template = {
label: "Action Label",
type: "button",
icon: true,
link: "/",
link: "/"
},
itemProps: (item) => ({ label: item.label }),
itemProps: (item) => ({ label: item.label })
},
fields: [
{
label: "Label",
name: "label",
type: "string",
type: "string"
},
{
label: "Type",
@@ -138,20 +138,20 @@ export const heroBlockSchema: Template = {
type: "string",
options: [
{ label: "Button", value: "button" },
{ label: "Link", value: "link" },
],
{ label: "Link", value: "link" }
]
},
{
label: "Icon",
name: "icon",
type: "boolean",
type: "boolean"
},
{
label: "Link",
name: "link",
type: "string",
},
],
type: "string"
}
]
},
{
type: "object",
@@ -161,14 +161,14 @@ export const heroBlockSchema: Template = {
{
name: "src",
label: "Image Source",
type: "image",
type: "image"
},
{
name: "alt",
label: "Alt Text",
type: "string",
},
],
type: "string"
}
]
},
{
type: "string",
@@ -177,8 +177,8 @@ export const heroBlockSchema: Template = {
options: [
{ label: "Default", value: "default" },
{ label: "Tint", value: "tint" },
{ label: "Primary", value: "primary" },
],
},
],
{ label: "Primary", value: "primary" }
]
}
]
};

View File

@@ -1,7 +1,7 @@
import React from "react";
import { Container } from "../util/container";
import { Section } from "../util/section";
import type {Template, TinaTemplate} from "tinacms";
import type { Template } from "tinacms";
import { PageBlocksTestimonial } from "../../tina/__generated__/types";
import { tinaField } from "tinacms/dist/react";

View File

@@ -4,6 +4,7 @@ import { FaFacebookF, FaGithub, FaTwitter } from "react-icons/fa";
import { AiFillInstagram } from "react-icons/ai";
import { Container } from "../../util/container";
import { RawRenderer } from "./rawRenderer";
import { ObjectField } from "@tinacms/schema-tools/dist/types";
export const Footer = ({ data, rawData }) => {
const socialIconClasses = "h-7 w-auto";
@@ -16,7 +17,7 @@ export const Footer = ({ data, rawData }) => {
purple: "text-purple-500 dark:text-purple-400 hover:text-purple-300",
orange: "text-orange-500 dark:text-orange-400 hover:text-orange-300",
yellow: "text-yellow-500 dark:text-yellow-400 hover:text-yellow-300",
primary: "text-white opacity-80 hover:opacity-100",
primary: "text-white opacity-80 hover:opacity-100"
};
const footerColor = {
@@ -30,8 +31,8 @@ export const Footer = ({ data, rawData }) => {
pink: "text-white from-pink-500 to-pink-600",
purple: "text-white from-purple-500 to-purple-600",
orange: "text-white from-orange-500 to-orange-600",
yellow: "text-white from-yellow-500 to-yellow-600",
},
yellow: "text-white from-yellow-500 to-yellow-600"
}
};
const footerColorCss = footerColor.default;
@@ -43,8 +44,7 @@ export const Footer = ({ data, rawData }) => {
<Link
href="/"
className="group mx-2 flex items-center font-bold tracking-tight text-gray-400 dark:text-gray-300 opacity-50 hover:opacity-100 transition duration-150 ease-out whitespace-nowrap"
>
</Link>
/>
<div className="flex gap-4">
{ data.social && data.social.facebook && (
<a
@@ -54,7 +54,7 @@ export const Footer = ({ data, rawData }) => {
>
<FaFacebookF
className={ `${ socialIconClasses } ${
socialIconColorClasses["primary"]
socialIconColorClasses.primary
}` }
/>
</a>
@@ -67,7 +67,7 @@ export const Footer = ({ data, rawData }) => {
>
<FaTwitter
className={ `${ socialIconClasses } ${
socialIconColorClasses["primary"]
socialIconColorClasses.primary
}` }
/>
</a>
@@ -80,7 +80,7 @@ export const Footer = ({ data, rawData }) => {
>
<AiFillInstagram
className={ `${ socialIconClasses } ${
socialIconColorClasses["primary"]
socialIconColorClasses.primary
}` }
/>
</a>
@@ -93,7 +93,7 @@ export const Footer = ({ data, rawData }) => {
>
<FaGithub
className={ `${ socialIconClasses } ${
socialIconColorClasses["primary"]
socialIconColorClasses.primary
}` }
/>
</a>
@@ -103,10 +103,44 @@ export const Footer = ({ data, rawData }) => {
</div>
<div
className={ `absolute h-1 bg-gradient-to-r from-transparent ${
data.color === "primary" ? `via-white` : `via-black dark:via-white`
data.color === "primary" ? "via-white" : "via-black dark:via-white"
} to-transparent top-0 left-4 right-4 opacity-5` }
></div>
/>
</Container>
</footer>
);
};
export const footerSchema: ObjectField = {
type: "object",
label: "Footer",
name: "footer",
fields: [
{
type: "object",
label: "Social Links",
name: "social",
fields: [
{
type: "string",
label: "Facebook",
name: "facebook"
},
{
type: "string",
label: "Twitter",
name: "twitter"
},
{
type: "string",
label: "Instagram",
name: "instagram"
},
{
type: "string",
label: "Github",
name: "github"
}
]
}]
};

View File

@@ -11,7 +11,7 @@ export const RawRenderer = ({ rawData, parentColor }) => {
pink: "text-pink-500",
purple: "text-purple-500",
orange: "text-orange-500",
yellow: "text-yellow-600",
yellow: "text-yellow-600"
};
const [isOpen, setIsOpen] = useState(false);
@@ -36,10 +36,10 @@ export const RawRenderer = ({ rawData, parentColor }) => {
<span
className={ `absolute w-full h-full left-0 top-0 rounded -z-1 ${
parentColor === "primary"
? `bg-white opacity-80`
: `bg-current opacity-15`
? "bg-white opacity-80"
: "bg-current opacity-15"
}` }
></span>
/>
</button>
<Transition appear show={ isOpen } as={ Fragment }>
<Dialog

View File

@@ -3,6 +3,7 @@ import Link from "next/link";
import { tinaField } from "tinacms/dist/react";
import defaultLogo from "../../public/logo.png";
import { GlobalHeader } from "../../tina/__generated__/types";
import { ObjectField } from "@tinacms/schema-tools/dist/types";
export const Header = ({ data }: { data: GlobalHeader }) => {
return (
@@ -23,9 +24,9 @@ export const Header = ({ data }: { data: GlobalHeader }) => {
<button className="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"
aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
<span className="navbar-toggler-icon" />
</button>
<div className={`flex items-center` } id="navbarSupportedContent">
<div className={ "flex items-center" } id="navbarSupportedContent">
<ul className="flex md:flex-row">
{ data.nav &&
data.nav.map((item, i) => {
@@ -54,3 +55,63 @@ export const Header = ({ data }: { data: GlobalHeader }) => {
</nav>
);
};
export const headerSchema: ObjectField = {
type: "object",
label: "Header",
name: "header",
fields: [
{
type: "string",
label: "Page Title",
name: "pageTitle"
},
{
type: "string",
label: "Title",
name: "title"
},
{
type: "string",
label: "Subtitle",
name: "subtitle"
},
{
type: "image",
label: "Logo",
name: "logoSrc"
},
{
type: "object",
label: "Nav Links",
name: "nav",
list: true,
ui: {
itemProps: (item) => {
return { label: item?.label };
},
defaultItem: {
href: "home",
label: "Home",
external: false
}
},
fields: [
{
type: "string",
label: "Link",
name: "href"
},
{
type: "string",
label: "Label",
name: "label"
},
{
type: "boolean",
label: "External",
name: "external"
}
]
}]
};

View File

@@ -8,7 +8,7 @@ import { Global } from "../../tina/__generated__/types";
export const Layout = ({
rawData = {},
data = layoutData,
children,
children
}: {
rawData?: object;
data?: Omit<Global, "id" | "_sys" | "_values">;

View File

@@ -108,7 +108,7 @@ const components: Components<{
<span className="flex items-center justify-center">
<img src={ props.url } alt={ props.alt } />
</span>
),
)
};
export const Post = (props: PostType) => {
@@ -123,7 +123,7 @@ export const Post = (props: PostType) => {
orange:
"from-orange-300 to-orange-600 dark:from-orange-200 dark:to-orange-500",
yellow:
"from-yellow-400 to-yellow-500 dark:from-yellow-300 dark:to-yellow-500",
"from-yellow-400 to-yellow-500 dark:from-yellow-300 dark:to-yellow-500"
};
const date = new Date(props.date);
@@ -134,13 +134,13 @@ export const Post = (props: PostType) => {
return (
<Section className="flex-1">
<Container width="small" className={`flex-1 pb-2`} size="large">
<Container width="small" className={ "flex-1 pb-2" } size="large">
<h2
data-tina-field={ tinaField(props, "title") }
className={`w-full relative mb-8 text-6xl font-extrabold tracking-normal text-center title-font`}
className={ "w-full relative mb-8 text-6xl font-extrabold tracking-normal text-center title-font" }
>
<span
className={`bg-clip-text text-transparent bg-gradient-to-r`}
className={ "bg-clip-text text-transparent bg-gradient-to-r" }
>
{ props.title }
</span>
@@ -197,7 +197,7 @@ export const Post = (props: PostType) => {
</div>
</div>
) }
<Container className={`flex-1 pt-4`} width="small" size="large">
<Container className={ "flex-1 pt-4" } width="small" size="large">
<div
data-tina-field={ tinaField(props, "_body") }
className="prose dark:prose-dark w-full max-w-none"

View File

@@ -18,11 +18,11 @@ export const Posts = ({ data }: { data: PostsType[] }) => {
return (
<Link
key={ post._sys.filename }
href={`/posts/` + post._sys.filename}
href={ "/posts/" + post._sys.filename }
className="group block px-6 sm:px-8 md:px-10 py-10 mb-8 last:mb-0 bg-gray-50 bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-1000 rounded-md shadow-sm transition-all duration-150 ease-out hover:shadow-md hover:to-gray-50 dark:hover:to-gray-800"
>
<h3
className={`text-gray-700 dark:text-white text-3xl lg:text-4xl font-semibold title-font mb-5 transition-all duration-150 ease-out`}
className={ "text-gray-700 dark:text-white text-3xl lg:text-4xl font-semibold title-font mb-5 transition-all duration-150 ease-out" }
>
{ post.title }{ " " }
<span className="inline-block opacity-0 group-hover:opacity-100 transition-all duration-300 ease-out">

View File

@@ -7,7 +7,7 @@ import { tinaField } from "tinacms/dist/react";
export const Actions = ({
parentColor = "default",
className = "",
actions,
actions
}: {
parentColor: string;
className: string;
@@ -25,7 +25,7 @@ export const Actions = ({
orange:
"text-white bg-orange-500 hover:bg-orange-600 bg-gradient-to-r from-orange-400 to-orange-600 hover:from-orange-400 hover:to-orange-500",
yellow:
"text-gray-800 bg-yellow-500 hover:bg-yellow-600 bg-gradient-to-r from-yellow-400 to-yellow-600 hover:from-yellow-400 hover:to-yellow-500",
"text-gray-800 bg-yellow-500 hover:bg-yellow-600 bg-gradient-to-r from-yellow-400 to-yellow-600 hover:from-yellow-400 hover:to-yellow-500"
};
const invertedButtonColorClasses = {
@@ -40,7 +40,7 @@ export const Actions = ({
orange:
"text-orange-500 bg-white hover:bg-gray-50 bg-gradient-to-r from-gray-50 to-white hover:to-gray-100",
yellow:
"text-yellow-500 bg-white hover:bg-gray-50 bg-gradient-to-r from-gray-50 to-white hover:to-gray-100",
"text-yellow-500 bg-white hover:bg-gray-50 bg-gradient-to-r from-gray-50 to-white hover:to-gray-100"
};
const linkButtonColorClasses = {
@@ -55,13 +55,13 @@ export const Actions = ({
orange:
"text-orange-600 dark:text-orange-400 hover:text-orange-400 dark:hover:text-orange-200",
yellow:
"text-yellow-600 dark:text-yellow-400 hover:text-yellow-400 dark:hover:text-yellow-200",
"text-yellow-600 dark:text-yellow-400 hover:text-yellow-400 dark:hover:text-yellow-200"
};
return (
<div className={ `flex flex-wrap items-center gap-y-4 gap-x-6 ${ className }` }>
{ actions &&
actions.map(function (action, index) {
actions.map((action, index) => {
let element = null;
if (action.type === "button") {
element = (
@@ -69,12 +69,12 @@ export const Actions = ({
<button
data-tina-field={ tinaField(action) }
className={ `z-10 relative flex items-center px-7 py-3 font-semibold text-lg transition duration-150 ease-out rounded-lg transform focus:shadow-outline focus:outline-none focus:ring-2 ring-offset-current ring-offset-2 whitespace-nowrap ${
invertedButtonColorClasses["blue"] }`}
invertedButtonColorClasses.blue }` }
>
{ action.label }
{ action.icon && (
<BiRightArrowAlt
className={`ml-1 -mr-1 w-6 h-6 opacity-80`}
className={ "ml-1 -mr-1 w-6 h-6 opacity-80" }
/>
) }
</button>
@@ -94,7 +94,7 @@ export const Actions = ({
>
{ action.label }
{ action.icon && (
<BiRightArrowAlt className={`ml-0 mr-0 w-6 h-6 opacity-80`} />
<BiRightArrowAlt className={ "ml-0 mr-0 w-6 h-6 opacity-80" } />
) }
</Link>
);

View File

@@ -2,7 +2,6 @@ import * as React from "react";
import { useEffect, useRef, useState } from "react";
import { tinaField } from "tinacms/dist/react";
import { ObjectField } from "@tinacms/schema-tools/dist/types";
import {SectionElement} from "@react-types/shared";
interface AnchoringProps {
text?: string, // Default: Découvrez-en plus !
@@ -26,15 +25,15 @@ export const Anchoring = (props: AnchoringProps) => {
behavior: "smooth",
block: "start"
});
}
};
useEffect(() => {
handleScrollOpacity(); // Initialize opacity on mount
window.addEventListener('scroll', handleScrollOpacity);
window.addEventListener("scroll", handleScrollOpacity);
return () => {
window.removeEventListener('scroll', handleScrollOpacity);
window.removeEventListener("scroll", handleScrollOpacity);
};
}, []);
@@ -62,7 +61,7 @@ export const anchoringSchema: ObjectField = {
text: "Découvrez-en plus !",
linkTo: "#main-page",
enabled: true
},
}
},
fields: [
{

View File

@@ -12,13 +12,13 @@ export const Container = ({
small: "py-8",
medium: "py-12",
large: "py-24",
default: "py-12",
default: "py-12"
};
const widthClass = {
small: "max-w-4xl",
medium: "max-w-5xl",
large: "max-w-7xl",
custom: "",
custom: ""
};
return (

View File

@@ -24,7 +24,7 @@ export const IconOptions = {
/>
</svg>
),
...BoxIcons,
...BoxIcons
};
const iconColorClass: {
@@ -32,40 +32,40 @@ const iconColorClass: {
} = {
blue: {
regular: "text-blue-400",
circle: "bg-blue-400 dark:bg-blue-500 text-blue-50",
circle: "bg-blue-400 dark:bg-blue-500 text-blue-50"
},
teal: {
regular: "text-teal-400",
circle: "bg-teal-400 dark:bg-teal-500 text-teal-50",
circle: "bg-teal-400 dark:bg-teal-500 text-teal-50"
},
green: {
regular: "text-green-400",
circle: "bg-green-400 dark:bg-green-500 text-green-50",
circle: "bg-green-400 dark:bg-green-500 text-green-50"
},
red: {
regular: "text-red-400",
circle: "bg-red-400 dark:bg-red-500 text-red-50",
circle: "bg-red-400 dark:bg-red-500 text-red-50"
},
pink: {
regular: "text-pink-400",
circle: "bg-pink-400 dark:bg-pink-500 text-pink-50",
circle: "bg-pink-400 dark:bg-pink-500 text-pink-50"
},
purple: {
regular: "text-purple-400",
circle: "bg-purple-400 dark:bg-purple-500 text-purple-50",
circle: "bg-purple-400 dark:bg-purple-500 text-purple-50"
},
orange: {
regular: "text-orange-400",
circle: "bg-orange-400 dark:bg-orange-500 text-orange-50",
circle: "bg-orange-400 dark:bg-orange-500 text-orange-50"
},
yellow: {
regular: "text-yellow-400",
circle: "bg-yellow-400 dark:bg-yellow-500 text-yellow-50",
circle: "bg-yellow-400 dark:bg-yellow-500 text-yellow-50"
},
white: {
regular: "text-white opacity-80",
circle: "bg-white-400 dark:bg-white-500 text-white-50",
},
circle: "bg-white-400 dark:bg-white-500 text-white-50"
}
};
const iconSizeClass = {
@@ -74,14 +74,14 @@ const iconSizeClass = {
medium: "w-12 h-12 flex-shrink-0",
large: "w-14 h-14 flex-shrink-0",
xl: "w-16 h-16 flex-shrink-0",
custom: "",
custom: ""
};
export const Icon = ({
data,
parentColor = "",
className = "",
tinaField = "",
tinaField = ""
}) => {
if (IconOptions[data.name] === null || IconOptions[data.name] === undefined) {
return null;
@@ -107,7 +107,7 @@ export const Icon = ({
<IconSVG className="w-2/3 h-2/3" />
</div>
);
} else {
}
const iconColorClasses =
iconColorClass[parentColor === "primary" && (iconColor === "primary") ? "white" : iconColor]?.regular || "white";
return (
@@ -116,7 +116,6 @@ export const Icon = ({
className={ `${ iconSizeClasses } ${ iconColorClasses } ${ className }` }
/>
);
}
};
export const iconSchema: ObjectField = {
@@ -129,16 +128,16 @@ export const iconSchema: ObjectField = {
label: "Icon",
name: "name",
ui: {
component: (props) => IconPickerInput(props),
},
component: (props) => IconPickerInput(props)
}
},
{
type: "string",
label: "Color",
name: "color",
ui: {
component: () => ColorPickerInput,
},
component: () => ColorPickerInput
}
},
{
name: "style",
@@ -147,13 +146,13 @@ export const iconSchema: ObjectField = {
options: [
{
label: "Circle",
value: "circle",
value: "circle"
},
{
label: "Float",
value: "float",
},
],
},
],
value: "float"
}
]
}
]
};

View File

@@ -17,8 +17,8 @@ export const Section = ({ children, color = "", className = "" }) => {
orange:
"text-white bg-orange-500 bg-gradient-to-br from-orange-500 to-orange-600",
yellow:
"text-white bg-yellow-500 bg-gradient-to-br from-yellow-500 to-yellow-600",
},
"text-white bg-yellow-500 bg-gradient-to-br from-yellow-500 to-yellow-600"
}
};
const sectionColorCss = sectionColor[color]
? sectionColor[color]

View File

@@ -76,3 +76,6 @@ blocks:

View File

@@ -17,9 +17,11 @@
"@types/react": "^17.0.35",
"@types/styled-components": "^5.1.15",
"@typescript-eslint/eslint-plugin": "^5.20.0",
"@typescript-eslint/parser": "^5.20.0",
"@typescript-eslint/parser": "^6.5.0",
"autoprefixer": "^10.4.0",
"eslint": "^8.13.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"postcss": "^8.3.11",
"postcss-import": "^14.0.2",
"postcss-nesting": "^10.1.0"

View File

@@ -14,9 +14,9 @@ export default function FourOhFour() {
label: "Return Home",
type: "button",
icon: true,
link: "/",
},
],
link: "/"
}
]
} }
/>
</Layout>

View File

@@ -19,14 +19,14 @@ export default function HomePage(
export const getStaticProps = async ({ params }) => {
const tinaProps = await client.queries.contentQuery({
relativePath: `${params.filename}.md`,
relativePath: `${ params.filename }.md`
});
const props = {
...tinaProps,
enableVisualEditing: process.env.VERCEL_ENV === "preview",
enableVisualEditing: process.env.VERCEL_ENV === "preview"
};
return {
props: JSON.parse(JSON.stringify(props)) as typeof props,
props: JSON.parse(JSON.stringify(props)) as typeof props
};
};
@@ -34,8 +34,8 @@ export const getStaticPaths = async () => {
const pagesListData = await client.queries.pageConnection();
return {
paths: pagesListData.data.pageConnection?.edges?.map((page) => ({
params: { filename: page?.node?._sys.filename },
params: { filename: page?.node?._sys.filename }
})),
fallback: false,
fallback: false
};
};

View File

@@ -25,8 +25,8 @@ export const getStaticProps = async () => {
const tinaProps = await client.queries.pageQuery();
return {
props: {
...tinaProps,
},
...tinaProps
}
};
};

View File

@@ -11,7 +11,7 @@ export default function BlogPostPage(
const { data } = useTina({
query: props.query,
variables: props.variables,
data: props.data,
data: props.data
});
if (data && data.post) {
return (
@@ -29,12 +29,12 @@ export default function BlogPostPage(
export const getStaticProps = async ({ params }) => {
const tinaProps = await client.queries.blogPostQuery({
relativePath: `${params.filename}.mdx`,
relativePath: `${ params.filename }.mdx`
});
return {
props: {
...tinaProps,
},
...tinaProps
}
};
};
@@ -49,9 +49,9 @@ export const getStaticPaths = async () => {
const postsListData = await client.queries.postConnection();
return {
paths: postsListData.data.postConnection.edges.map((post) => ({
params: { filename: post.node._sys.filename },
params: { filename: post.node._sys.filename }
})),
fallback: "blocking",
fallback: "blocking"
};
};

View File

@@ -3,8 +3,9 @@ import { contentBlockSchema } from "../components/blocks/content";
import { featureBlockSchema } from "../components/blocks/features";
import { heroBlockSchema } from "../components/blocks/hero";
import { testimonialBlockSchema } from "../components/blocks/testimonial";
import { ColorPickerInput } from "./fields/color";
import { carouselBlockSchema } from "../components/blocks/carousel";
import { headerSchema } from "../components/layout/header";
import { footerSchema } from "../components/layout/footer/footer";
const config = defineConfig({
clientId: process.env.NEXT_PUBLIC_TINA_CLIENT_ID!,
@@ -22,12 +23,12 @@ const config = defineConfig({
// this is the config for the tina cloud media store
tina: {
publicFolder: "public",
mediaRoot: "uploads",
},
mediaRoot: "uploads"
}
},
build: {
publicFolder: "public", // The public asset folder for your framework
outputFolder: "admin", // within the public folder
outputFolder: "admin" // within the public folder
},
schema: {
collections: [
@@ -39,7 +40,7 @@ const config = defineConfig({
ui: {
router: ({ document }) => {
return `/posts/${ document._sys.filename }`;
},
}
},
fields: [
{
@@ -47,23 +48,23 @@ const config = defineConfig({
label: "Title",
name: "title",
isTitle: true,
required: true,
required: true
},
{
type: "image",
name: "heroImg",
label: "Hero Image",
label: "Hero Image"
},
{
type: "rich-text",
label: "Excerpt",
name: "excerpt",
name: "excerpt"
},
{
type: "reference",
label: "Author",
name: "author",
collections: ["author"],
collections: ["author"]
},
{
type: "datetime",
@@ -71,8 +72,8 @@ const config = defineConfig({
name: "date",
ui: {
dateFormat: "MMMM DD YYYY",
timeFormat: "hh:mm A",
},
timeFormat: "hh:mm A"
}
},
{
type: "rich-text",
@@ -88,9 +89,9 @@ const config = defineConfig({
name: "format",
label: "Format",
type: "string",
options: ["utc", "iso", "local"],
},
],
options: ["utc", "iso", "local"]
}
]
},
{
name: "BlockQuote",
@@ -99,14 +100,14 @@ const config = defineConfig({
{
name: "children",
label: "Quote",
type: "rich-text",
type: "rich-text"
},
{
name: "authorName",
label: "Author",
type: "string",
},
],
type: "string"
}
]
},
{
name: "NewsletterSignup",
@@ -115,35 +116,35 @@ const config = defineConfig({
{
name: "children",
label: "CTA",
type: "rich-text",
type: "rich-text"
},
{
name: "placeholder",
label: "Placeholder",
type: "string",
type: "string"
},
{
name: "buttonText",
label: "Button Text",
type: "string",
type: "string"
},
{
name: "disclaimer",
label: "Disclaimer",
type: "rich-text",
},
type: "rich-text"
}
],
ui: {
defaultItem: {
placeholder: "Enter your email",
buttonText: "Notify Me",
},
},
},
],
isBody: true,
},
buttonText: "Notify Me"
}
}
}
],
isBody: true
}
]
},
{
label: "Global",
@@ -151,104 +152,12 @@ const config = defineConfig({
path: "content/global",
format: "json",
ui: {
global: true,
global: true
},
fields: [
{
type: "object",
label: "Header",
name: "header",
fields: [
{
type: "string",
label: "Page Title",
name: "pageTitle",
},
{
type: "string",
label: "Title",
name: "title",
},
{
type: "string",
label: "Subtitle",
name: "subtitle",
},
{
type: "image",
label: "Logo",
name: "logoSrc"
},
{
type: "object",
label: "Nav Links",
name: "nav",
list: true,
ui: {
itemProps: (item) => {
return { label: item?.label };
},
defaultItem: {
href: "home",
label: "Home",
external: false
},
},
fields: [
{
type: "string",
label: "Link",
name: "href",
},
{
type: "string",
label: "Label",
name: "label",
},
{
type: "boolean",
label: "External",
name: "external",
}
],
},
],
},
{
type: "object",
label: "Footer",
name: "footer",
fields: [
{
type: "object",
label: "Social Links",
name: "social",
fields: [
{
type: "string",
label: "Facebook",
name: "facebook",
},
{
type: "string",
label: "Twitter",
name: "twitter",
},
{
type: "string",
label: "Instagram",
name: "instagram",
},
{
type: "string",
label: "Github",
name: "github",
},
],
},
],
},
],
headerSchema,
footerSchema
]
},
{
label: "Authors",
@@ -261,14 +170,14 @@ const config = defineConfig({
label: "Name",
name: "name",
isTitle: true,
required: true,
required: true
},
{
type: "image",
label: "Avatar",
name: "avatar",
},
],
name: "avatar"
}
]
},
{
label: "Pages",
@@ -277,13 +186,13 @@ const config = defineConfig({
ui: {
router: ({ document }) => {
if (document._sys.filename === "home") {
return `/`;
return "/";
}
if (document._sys.filename === "about") {
return `/about`;
return "/about";
}
return undefined;
},
}
},
fields: [
{
@@ -293,7 +202,7 @@ const config = defineConfig({
description:
"The title of the page. This is used to display the title in the CMS",
isTitle: true,
required: true,
required: true
},
{
type: "object",
@@ -301,7 +210,7 @@ const config = defineConfig({
name: "blocks",
label: "Sections",
ui: {
visualSelector: true,
visualSelector: true
},
templates: [
heroBlockSchema,
@@ -311,12 +220,12 @@ const config = defineConfig({
testimonialBlockSchema,
// @ts-ignore
carouselBlockSchema
],
},
],
},
],
},
]
}
]
}
]
}
});
export default config;

View File

@@ -10,7 +10,7 @@ export const colorOptions = [
"red",
"pink",
"purple",
"white",
"white"
];
export const ColorPickerInput = wrapFieldsWithMeta(({ input }) => {
@@ -23,7 +23,7 @@ export const ColorPickerInput = wrapFieldsWithMeta(({ input }) => {
red: "bg-red-500 border-red-600",
pink: "bg-pink-500 border-pink-600",
purple: "bg-purple-500 border-purple-600",
white: "bg-white border-gray-150",
white: "bg-white border-gray-150"
};
return (
@@ -43,7 +43,7 @@ export const ColorPickerInput = wrapFieldsWithMeta(({ input }) => {
onClick={ () => {
input.onChange(color);
} }
></button>
/>
);
}) }
</div>

View File

@@ -9,9 +9,8 @@ const parseIconName = (name: string) => {
const splitName = name.split(/(?=[A-Z])/);
if (splitName.length > 1) {
return splitName.slice(1).join(" ");
} else {
return name;
}
return name;
};
export const IconPickerInput = wrapFieldsWithMeta(({ input }) => {
@@ -112,7 +111,7 @@ export const IconPickerInput = wrapFieldsWithMeta(({ input }) => {
data={ {
name: name,
size: "custom",
color: "blue",
color: "blue"
} }
className="w-7 h-auto"
/>

760
yarn.lock

File diff suppressed because it is too large Load Diff