Linted the whole project with eslint
This commit was merged in pull request #3.
This commit is contained in:
503
.eslintrc
Normal file
503
.eslintrc
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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 } />
|
||||
|
||||
@@ -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
|
||||
}
|
||||
],
|
||||
]
|
||||
};
|
||||
|
||||
@@ -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" }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -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" }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -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" }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}]
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}]
|
||||
};
|
||||
@@ -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">;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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: [
|
||||
{
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -76,3 +76,6 @@ blocks:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -14,9 +14,9 @@ export default function FourOhFour() {
|
||||
label: "Return Home",
|
||||
type: "button",
|
||||
icon: true,
|
||||
link: "/",
|
||||
},
|
||||
],
|
||||
link: "/"
|
||||
}
|
||||
]
|
||||
} }
|
||||
/>
|
||||
</Layout>
|
||||
|
||||
@@ -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
|
||||
};
|
||||
};
|
||||
|
||||
@@ -25,8 +25,8 @@ export const getStaticProps = async () => {
|
||||
const tinaProps = await client.queries.pageQuery();
|
||||
return {
|
||||
props: {
|
||||
...tinaProps,
|
||||
},
|
||||
...tinaProps
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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"
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
191
tina/config.tsx
191
tina/config.tsx
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user