✨(demo) new demo
This new demo aims to take advantage of all the new Cunningham's components. The old demo was kind of a draft, this new one gives a better overview of what Cunningham is capable of.
This commit is contained in:
5
.changeset/shiny-pumpkins-shave.md
Normal file
5
.changeset/shiny-pumpkins-shave.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"cunningham-demo": major
|
||||||
|
---
|
||||||
|
|
||||||
|
new demo
|
||||||
@@ -1,14 +1,5 @@
|
|||||||
import { Configuration } from "@openfun/cunningham-react";
|
import { Configuration } from "@openfun/cunningham-react";
|
||||||
|
|
||||||
const config: Configuration = {
|
const defaultConfig: Configuration = { themes: {} };
|
||||||
themes: {
|
|
||||||
default: {
|
export default defaultConfig;
|
||||||
components: {
|
|
||||||
button: {
|
|
||||||
"border-radius": "30px",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
export default config;
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@faker-js/faker": "8.3.1",
|
||||||
"@openfun/cunningham-react": "*",
|
"@openfun/cunningham-react": "*",
|
||||||
"@openfun/cunningham-tokens": "*",
|
"@openfun/cunningham-tokens": "*",
|
||||||
"@openfun/typescript-configs": "*",
|
"@openfun/typescript-configs": "*",
|
||||||
|
|||||||
BIN
apps/demo/public/pattern_dark.png
Normal file
BIN
apps/demo/public/pattern_dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
BIN
apps/demo/public/pattern_default.png
Normal file
BIN
apps/demo/public/pattern_default.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
@@ -1,62 +1,69 @@
|
|||||||
import {
|
import { Button, CunninghamProvider } from "@openfun/cunningham-react";
|
||||||
Button,
|
import React, { useEffect, useState } from "react";
|
||||||
CunninghamProvider,
|
import { Create } from "./Create";
|
||||||
Pagination,
|
import { Home } from "./Home";
|
||||||
Select,
|
|
||||||
SUPPORTED_LOCALES,
|
|
||||||
Switch,
|
|
||||||
usePagination,
|
|
||||||
} from "@openfun/cunningham-react";
|
|
||||||
import React, { useState } from "react";
|
|
||||||
import { tokens } from "./cunningham-tokens";
|
|
||||||
|
|
||||||
enum Theme {
|
enum Theme {
|
||||||
DEFAULT = "default",
|
DEFAULT = "default",
|
||||||
DARK = "dark",
|
DARK = "dark",
|
||||||
}
|
}
|
||||||
|
|
||||||
const THEMES: Theme[] = [Theme.DEFAULT, Theme.DARK];
|
export enum Page {
|
||||||
|
HOME,
|
||||||
|
CREATE,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PageProps {
|
||||||
|
changePage: (page: Page) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const preferredScheme = window.matchMedia("(prefers-color-scheme: dark)")
|
||||||
|
.matches
|
||||||
|
? Theme.DARK
|
||||||
|
: Theme.DEFAULT;
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
const pagination = usePagination({ defaultPage: 50, defaultPagesCount: 100 });
|
const [locale] = useState("en-US");
|
||||||
const [locale, setLocale] = useState("en-US");
|
const [theme, setTheme] = useState<Theme>(preferredScheme);
|
||||||
const [theme, setTheme] = useState<Theme>(Theme.DEFAULT);
|
const [page, setPage] = useState<Page>(Page.HOME);
|
||||||
|
const handleThemeChange = (event: MediaQueryListEvent) =>
|
||||||
|
setTheme(event.matches ? Theme.DARK : Theme.DEFAULT);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const query = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
query.addEventListener("change", handleThemeChange);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
query.removeEventListener("change", handleThemeChange);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CunninghamProvider currentLocale={locale} theme={theme}>
|
<CunninghamProvider currentLocale={locale} theme={theme}>
|
||||||
<div className="center">
|
<div className="container">
|
||||||
<h1 className="clr-greyscale-900">Cunningham Demo.</h1>
|
<img
|
||||||
|
className="pattern"
|
||||||
<div className="mb-s">
|
src={
|
||||||
<Select
|
theme === Theme.DARK ? "pattern_dark.png" : "pattern_default.png"
|
||||||
label="Locale"
|
}
|
||||||
options={SUPPORTED_LOCALES.map((v) => ({
|
alt="Background pattern"
|
||||||
label: v,
|
|
||||||
}))}
|
|
||||||
clearable={false}
|
|
||||||
value={locale}
|
|
||||||
onChange={(e) => setLocale(e.target.value as string)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Select
|
|
||||||
label="Theme"
|
|
||||||
options={THEMES.map((v) => ({
|
|
||||||
label: v,
|
|
||||||
}))}
|
|
||||||
clearable={false}
|
|
||||||
value={THEMES[0]}
|
|
||||||
onChange={(e) => setTheme(e.target.value as Theme)}
|
|
||||||
/>
|
/>
|
||||||
|
{page === Page.HOME && <Home changePage={(p) => setPage(p)} />}
|
||||||
|
{page === Page.CREATE && <Create changePage={(p) => setPage(p)} />}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="p-s">
|
<div className="theme-switch">
|
||||||
<Switch defaultChecked={true} label="Switch" />
|
<Button
|
||||||
</div>
|
color="tertiary"
|
||||||
<Button>World best button.</Button>
|
icon={
|
||||||
<h3 className="clr-greyscale-900">
|
<span className="material-icons">
|
||||||
Primary-500 color is{" "}
|
{theme === Theme.DARK ? "light_mode" : "dark_mode"}
|
||||||
{tokens.themes[theme].theme.colors["primary-500"]}
|
</span>
|
||||||
</h3>
|
}
|
||||||
<Pagination {...pagination} />
|
onClick={() => {
|
||||||
|
setTheme(theme === Theme.DARK ? Theme.DEFAULT : Theme.DARK);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</CunninghamProvider>
|
</CunninghamProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
168
apps/demo/src/Character.ts
Normal file
168
apps/demo/src/Character.ts
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
import { faker } from "@faker-js/faker";
|
||||||
|
|
||||||
|
export interface Character {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
gender: "male" | "female" | "other";
|
||||||
|
birthDate: Date;
|
||||||
|
firstAppearanceDate: Date;
|
||||||
|
lastAppearanceDate: Date;
|
||||||
|
isGuest: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const randomDates = () => {
|
||||||
|
return {
|
||||||
|
birthDate: faker.date.between({
|
||||||
|
from: "1950-01-01T00:00:00.000Z",
|
||||||
|
to: "1970-01-01T00:00:00.000Z",
|
||||||
|
}),
|
||||||
|
firstAppearanceDate: faker.date.between({
|
||||||
|
from: "1974-01-01T00:00:00.000Z",
|
||||||
|
to: "1984-01-01T00:00:00.000Z",
|
||||||
|
}),
|
||||||
|
lastAppearanceDate: faker.date.past(),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const database: Character[] = [
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Richie Cunningham",
|
||||||
|
gender: "male",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Joanie Cunningham",
|
||||||
|
gender: "female",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Arthur Fonzarelli",
|
||||||
|
gender: "male",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Marion Cunningham",
|
||||||
|
gender: "female",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Ralph Malph",
|
||||||
|
gender: "male",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Howard Cunningham",
|
||||||
|
gender: "male",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Marsha Simms",
|
||||||
|
gender: "female",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Warren Berlinger",
|
||||||
|
gender: "male",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Al Molinaro",
|
||||||
|
gender: "male",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Verna LaVerne",
|
||||||
|
gender: "female",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Arnold Takahashi",
|
||||||
|
gender: "male",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Linda Purl",
|
||||||
|
gender: "female",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Crystal Bernard",
|
||||||
|
gender: "female",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Heather O'Rourke",
|
||||||
|
gender: "female",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Scott Bernstein",
|
||||||
|
gender: "male",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Ed Peck",
|
||||||
|
gender: "male",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Beatrice Colen",
|
||||||
|
gender: "female",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Dody Goodman",
|
||||||
|
gender: "female",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Linda Dano",
|
||||||
|
gender: "female",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: "Gavan O'Herlihy",
|
||||||
|
gender: "male",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
},
|
||||||
|
];
|
||||||
132
apps/demo/src/Create.tsx
Normal file
132
apps/demo/src/Create.tsx
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
Alert,
|
||||||
|
AlertType,
|
||||||
|
Button,
|
||||||
|
Checkbox,
|
||||||
|
DatePicker,
|
||||||
|
DateRangePicker,
|
||||||
|
FileUploader,
|
||||||
|
Input,
|
||||||
|
Radio,
|
||||||
|
RadioGroup,
|
||||||
|
Select,
|
||||||
|
Switch,
|
||||||
|
TextArea,
|
||||||
|
ToastType,
|
||||||
|
useToastProvider,
|
||||||
|
} from "@openfun/cunningham-react";
|
||||||
|
import { faker } from "@faker-js/faker";
|
||||||
|
import { Character, database, randomDates } from "./Character";
|
||||||
|
import { Page, PageProps } from "./App";
|
||||||
|
|
||||||
|
export const Create = ({ changePage }: PageProps) => {
|
||||||
|
const { toast } = useToastProvider();
|
||||||
|
const inputRef = React.useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
const submit = () => {
|
||||||
|
const character: Character = {
|
||||||
|
id: faker.string.uuid(),
|
||||||
|
name: inputRef.current?.value || "",
|
||||||
|
gender: "male",
|
||||||
|
isGuest: false,
|
||||||
|
...randomDates(),
|
||||||
|
};
|
||||||
|
database.unshift(character);
|
||||||
|
|
||||||
|
changePage(Page.HOME);
|
||||||
|
toast("Character created successfully", ToastType.SUCCESS);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="page__create clr-greyscale-900">
|
||||||
|
<h1>Add a character</h1>
|
||||||
|
<div className="card">
|
||||||
|
<h3 className="fw-bold fs-h3">General Information</h3>
|
||||||
|
<Alert type={AlertType.INFO}>
|
||||||
|
You are about to add a new character to the collection
|
||||||
|
</Alert>
|
||||||
|
<Input
|
||||||
|
ref={inputRef}
|
||||||
|
label="Name"
|
||||||
|
text="Enter first and last name"
|
||||||
|
fullWidth={true}
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
label="Gender"
|
||||||
|
fullWidth={true}
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
label: "Male",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Female",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Other",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<DatePicker label="Birth Date" fullWidth={true} />
|
||||||
|
<DateRangePicker
|
||||||
|
startLabel="First appearance"
|
||||||
|
endLabel="Last appearance"
|
||||||
|
fullWidth={true}
|
||||||
|
/>
|
||||||
|
<Checkbox label="This character is a guest" />
|
||||||
|
</div>
|
||||||
|
<div className="card mt-l">
|
||||||
|
<h3 className="fw-bold fs-h3">Bio</h3>
|
||||||
|
<Alert type={AlertType.WARNING}>
|
||||||
|
Please be exhaustive, every detail counts!
|
||||||
|
</Alert>
|
||||||
|
<TextArea
|
||||||
|
label="Biography"
|
||||||
|
text="Enter a detailed biography"
|
||||||
|
fullWidth={true}
|
||||||
|
rows={8}
|
||||||
|
/>
|
||||||
|
<RadioGroup>
|
||||||
|
<Radio
|
||||||
|
label="Appeared between 0 and 5 times"
|
||||||
|
name="occurences"
|
||||||
|
value="A"
|
||||||
|
/>
|
||||||
|
<Radio
|
||||||
|
label="Appeared between 6 and 10 times"
|
||||||
|
name="occurences"
|
||||||
|
value="B"
|
||||||
|
/>
|
||||||
|
<Radio
|
||||||
|
label="Appeared between 10 and 20 times"
|
||||||
|
name="occurences"
|
||||||
|
value="C"
|
||||||
|
/>
|
||||||
|
<Radio
|
||||||
|
label="Appeared between 20+ times"
|
||||||
|
name="occurences"
|
||||||
|
value="D"
|
||||||
|
/>
|
||||||
|
</RadioGroup>
|
||||||
|
<Switch label="Make this character public" />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4>Add pictures</h4>
|
||||||
|
|
||||||
|
<div className="mt-s">
|
||||||
|
<FileUploader
|
||||||
|
fullWidth={true}
|
||||||
|
text="JPG, PNG or GIF - Max file size 2MB"
|
||||||
|
multiple={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-l">
|
||||||
|
<Button fullWidth={true} onClick={() => submit()}>
|
||||||
|
Add character
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
141
apps/demo/src/Home.tsx
Normal file
141
apps/demo/src/Home.tsx
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
DataGrid,
|
||||||
|
SortModel,
|
||||||
|
ToastType,
|
||||||
|
usePagination,
|
||||||
|
useToastProvider,
|
||||||
|
} from "@openfun/cunningham-react";
|
||||||
|
import { Page, PageProps } from "./App";
|
||||||
|
import { database } from "./Character";
|
||||||
|
|
||||||
|
export const Home = ({ changePage }: PageProps) => {
|
||||||
|
const { toast } = useToastProvider();
|
||||||
|
const [rowSelection, setRowSelection] = useState({});
|
||||||
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
const pagination = usePagination({ defaultPage: 1 });
|
||||||
|
const [sortModel, setSortModel] = useState<SortModel>([
|
||||||
|
{
|
||||||
|
field: "lastName",
|
||||||
|
sort: "desc",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const [rows, setRows] = useState<typeof database>([]);
|
||||||
|
const [refresh, setRefresh] = useState(1);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Sort database. On your side this is supposed to be done on the server.
|
||||||
|
const sortKey = sortModel.length > 0 ? sortModel[0].field : "id";
|
||||||
|
const sortPolarity =
|
||||||
|
sortModel.length > 0 && sortModel[0].sort === "asc" ? 1 : -1;
|
||||||
|
const sortedDatabase = [...database].sort((a: any, b: any) => {
|
||||||
|
if (a[sortKey] < b[sortKey]) return -sortPolarity;
|
||||||
|
if (a[sortKey] > b[sortKey]) return sortPolarity;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
|
// Set the pagination length.
|
||||||
|
pagination.setPagesCount(
|
||||||
|
Math.ceil(sortedDatabase.length / pagination.pageSize),
|
||||||
|
);
|
||||||
|
// Select the rows to display on the current page.
|
||||||
|
setRows(
|
||||||
|
sortedDatabase.slice(
|
||||||
|
(pagination.page - 1) * pagination.pageSize,
|
||||||
|
pagination.page * pagination.pageSize,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
setIsLoading(false);
|
||||||
|
}, [pagination.page, sortModel, refresh]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="page__home">
|
||||||
|
<div className="page__home__title">
|
||||||
|
<h1 className="clr-greyscale-900">
|
||||||
|
{/* eslint-disable-next-line react/no-unescaped-entities */}
|
||||||
|
🍿Cunningham's <span className="clr-primary-400">Cast</span>
|
||||||
|
</h1>
|
||||||
|
<p className="clr-greyscale-600 fs-m fw-regular">
|
||||||
|
Happy Days is an American television sitcom that aired first-run from
|
||||||
|
January 15, 1974, to September 24, 1984, on ABC-TV
|
||||||
|
<br /> with a total of 255 half-hour episodes spanning over eleven
|
||||||
|
seasons. <br />
|
||||||
|
<br />
|
||||||
|
Created by Garry Marshall, the series presented an idealized vision of
|
||||||
|
life in the mid-1950s to mid-1960s Midwestern United States.
|
||||||
|
</p>
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
icon={<span className="material-icons">movie</span>}
|
||||||
|
onClick={() => changePage(Page.CREATE)}
|
||||||
|
>
|
||||||
|
Add character
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="card">
|
||||||
|
<DataGrid
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
field: "name",
|
||||||
|
headerName: "Name",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "gender",
|
||||||
|
headerName: "Gender",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "birthDate",
|
||||||
|
headerName: "Birth Date",
|
||||||
|
renderCell: (params) => {
|
||||||
|
return params.row.birthDate.toLocaleDateString();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "firstAppearanceDate",
|
||||||
|
headerName: "First Appearance",
|
||||||
|
renderCell: (params) => {
|
||||||
|
return params.row.firstAppearanceDate.toLocaleDateString();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "isGuest",
|
||||||
|
headerName: "Is Guest",
|
||||||
|
renderCell: (params) => {
|
||||||
|
return params.row.isGuest ? "yes" : "no";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "actions",
|
||||||
|
renderCell: (params) => (
|
||||||
|
<Button
|
||||||
|
color="tertiary-text"
|
||||||
|
size="small"
|
||||||
|
onClick={() => {
|
||||||
|
const index = database.findIndex(
|
||||||
|
(character) => character.id === params.row.id,
|
||||||
|
);
|
||||||
|
database.splice(index, 1);
|
||||||
|
setRefresh(refresh + 1);
|
||||||
|
toast("Character deleted successfully", ToastType.WARNING);
|
||||||
|
}}
|
||||||
|
icon={<span className="material-icons">delete</span>}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
rows={rows}
|
||||||
|
pagination={pagination}
|
||||||
|
sortModel={sortModel}
|
||||||
|
onSortModelChange={setSortModel}
|
||||||
|
isLoading={isLoading}
|
||||||
|
enableRowSelection={true}
|
||||||
|
rowSelection={rowSelection}
|
||||||
|
onRowSelectionChange={setRowSelection}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -106,7 +106,12 @@
|
|||||||
--c--theme--transitions--ease-out: cubic-bezier(0.33, 1, 0.68, 1);
|
--c--theme--transitions--ease-out: cubic-bezier(0.33, 1, 0.68, 1);
|
||||||
--c--theme--transitions--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
|
--c--theme--transitions--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
|
||||||
--c--theme--transitions--duration: 250ms;
|
--c--theme--transitions--duration: 250ms;
|
||||||
--c--components--button--border-radius: 30px;
|
--c--theme--breakpoints--xs: 0;
|
||||||
|
--c--theme--breakpoints--sm: 576px;
|
||||||
|
--c--theme--breakpoints--md: 768px;
|
||||||
|
--c--theme--breakpoints--lg: 992px;
|
||||||
|
--c--theme--breakpoints--xl: 1200px;
|
||||||
|
--c--theme--breakpoints--xxl: 1400px;
|
||||||
}
|
}
|
||||||
.cunningham-theme--dark{
|
.cunningham-theme--dark{
|
||||||
--c--theme--colors--greyscale-100: #182536;
|
--c--theme--colors--greyscale-100: #182536;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export const tokens = {"themes":{"default":{"theme":{"colors":{"secondary-text":"#555F6B","secondary-100":"#F2F7FC","secondary-200":"#EBF3FA","secondary-300":"#E2EEF8","secondary-400":"#DDEAF7","secondary-500":"#D4E5F5","secondary-600":"#C1D0DF","secondary-700":"#97A3AE","secondary-800":"#757E87","secondary-900":"#596067","info-text":"#FFFFFF","info-100":"#EBF2FC","info-200":"#8CB5EA","info-300":"#5894E1","info-400":"#377FDB","info-500":"#055FD2","info-600":"#0556BF","info-700":"#044395","info-800":"#033474","info-900":"#022858","greyscale-100":"#FAFAFB","greyscale-200":"#F3F4F4","greyscale-300":"#E7E8EA","greyscale-400":"#C2C6CA","greyscale-500":"#9EA3AA","greyscale-600":"#79818A","greyscale-700":"#555F6B","greyscale-800":"#303C4B","greyscale-900":"#0C1A2B","greyscale-000":"#FFFFFF","primary-100":"#EBF2FC","primary-200":"#8CB5EA","primary-300":"#5894E1","primary-400":"#377FDB","primary-500":"#055FD2","primary-600":"#0556BF","primary-700":"#044395","primary-800":"#033474","primary-900":"#022858","success-100":"#EFFCD3","success-200":"#DBFAA9","success-300":"#BEF27C","success-400":"#A0E659","success-500":"#76D628","success-600":"#5AB81D","success-700":"#419A14","success-800":"#2C7C0C","success-900":"#1D6607","warning-100":"#FFF8CD","warning-200":"#FFEF9B","warning-300":"#FFE469","warning-400":"#FFDA43","warning-500":"#FFC805","warning-600":"#DBA603","warning-700":"#B78702","warning-800":"#936901","warning-900":"#7A5400","danger-100":"#F4B0B0","danger-200":"#EE8A8A","danger-300":"#E65454","danger-400":"#E13333","danger-500":"#DA0000","danger-600":"#C60000","danger-700":"#9B0000","danger-800":"#780000","danger-900":"#5C0000","primary-text":"#FFFFFF","success-text":"#FFFFFF","warning-text":"#FFFFFF","danger-text":"#FFFFFF"},"font":{"sizes":{"h1":"1.75rem","h2":"1.375rem","h3":"1.125rem","h4":"0.8125rem","h5":"0.625rem","h6":"0.5rem","l":"1rem","m":"0.8125rem","s":"0.6875rem"},"weights":{"thin":200,"light":300,"regular":400,"medium":500,"bold":600,"extrabold":700,"black":800},"families":{"base":"\"Roboto Flex Variable\", sans-serif","accent":"\"Roboto Flex Variable\", sans-serif"},"letterSpacings":{"h1":"normal","h2":"normal","h3":"normal","h4":"normal","h5":"1px","h6":"normal","l":"normal","m":"normal","s":"normal"}},"spacings":{"xl":"4rem","l":"3rem","b":"1.625rem","s":"1rem","t":"0.5rem","st":"0.25rem"},"transitions":{"ease-in":"cubic-bezier(0.32, 0, 0.67, 0)","ease-out":"cubic-bezier(0.33, 1, 0.68, 1)","ease-in-out":"cubic-bezier(0.65, 0, 0.35, 1)","duration":"250ms"}},"components":{"button":{"border-radius":"30px"}}},"dark":{"theme":{"colors":{"greyscale-100":"#182536","greyscale-200":"#303C4B","greyscale-300":"#555F6B","greyscale-400":"#79818A","greyscale-500":"#9EA3AA","greyscale-600":"#C2C6CA","greyscale-700":"#E7E8EA","greyscale-800":"#F3F4F4","greyscale-900":"#FAFAFB","greyscale-000":"#0C1A2B","primary-100":"#3B4C62","primary-200":"#4D6481","primary-300":"#6381A6","primary-400":"#7FA5D5","primary-500":"#8CB5EA","primary-600":"#A3C4EE","primary-700":"#C3D8F4","primary-800":"#DDE9F8","primary-900":"#F4F8FD","success-100":"#EEF8D7","success-200":"#D9F1B2","success-300":"#BDE985","success-400":"#A0E25D","success-500":"#76D628","success-600":"#5BB520","success-700":"#43941A","success-800":"#307414","success-900":"#225D10","warning-100":"#F7F3D5","warning-200":"#F0E5AA","warning-300":"#E8D680","warning-400":"#E3C95F","warning-500":"#D9B32B","warning-600":"#BD9721","warning-700":"#9D7B1C","warning-800":"#7E6016","warning-900":"#684D12","danger-100":"#F8D0D0","danger-200":"#F09898","danger-300":"#F09898","danger-400":"#ED8585","danger-500":"#E96666","danger-600":"#DD6666","danger-700":"#C36666","danger-800":"#AE6666","danger-900":"#9D6666"}}}}};
|
export const tokens = {"themes":{"default":{"theme":{"colors":{"secondary-text":"#555F6B","secondary-100":"#F2F7FC","secondary-200":"#EBF3FA","secondary-300":"#E2EEF8","secondary-400":"#DDEAF7","secondary-500":"#D4E5F5","secondary-600":"#C1D0DF","secondary-700":"#97A3AE","secondary-800":"#757E87","secondary-900":"#596067","info-text":"#FFFFFF","info-100":"#EBF2FC","info-200":"#8CB5EA","info-300":"#5894E1","info-400":"#377FDB","info-500":"#055FD2","info-600":"#0556BF","info-700":"#044395","info-800":"#033474","info-900":"#022858","greyscale-100":"#FAFAFB","greyscale-200":"#F3F4F4","greyscale-300":"#E7E8EA","greyscale-400":"#C2C6CA","greyscale-500":"#9EA3AA","greyscale-600":"#79818A","greyscale-700":"#555F6B","greyscale-800":"#303C4B","greyscale-900":"#0C1A2B","greyscale-000":"#FFFFFF","primary-100":"#EBF2FC","primary-200":"#8CB5EA","primary-300":"#5894E1","primary-400":"#377FDB","primary-500":"#055FD2","primary-600":"#0556BF","primary-700":"#044395","primary-800":"#033474","primary-900":"#022858","success-100":"#EFFCD3","success-200":"#DBFAA9","success-300":"#BEF27C","success-400":"#A0E659","success-500":"#76D628","success-600":"#5AB81D","success-700":"#419A14","success-800":"#2C7C0C","success-900":"#1D6607","warning-100":"#FFF8CD","warning-200":"#FFEF9B","warning-300":"#FFE469","warning-400":"#FFDA43","warning-500":"#FFC805","warning-600":"#DBA603","warning-700":"#B78702","warning-800":"#936901","warning-900":"#7A5400","danger-100":"#F4B0B0","danger-200":"#EE8A8A","danger-300":"#E65454","danger-400":"#E13333","danger-500":"#DA0000","danger-600":"#C60000","danger-700":"#9B0000","danger-800":"#780000","danger-900":"#5C0000","primary-text":"#FFFFFF","success-text":"#FFFFFF","warning-text":"#FFFFFF","danger-text":"#FFFFFF"},"font":{"sizes":{"h1":"1.75rem","h2":"1.375rem","h3":"1.125rem","h4":"0.8125rem","h5":"0.625rem","h6":"0.5rem","l":"1rem","m":"0.8125rem","s":"0.6875rem"},"weights":{"thin":200,"light":300,"regular":400,"medium":500,"bold":600,"extrabold":700,"black":800},"families":{"base":"\"Roboto Flex Variable\", sans-serif","accent":"\"Roboto Flex Variable\", sans-serif"},"letterSpacings":{"h1":"normal","h2":"normal","h3":"normal","h4":"normal","h5":"1px","h6":"normal","l":"normal","m":"normal","s":"normal"}},"spacings":{"xl":"4rem","l":"3rem","b":"1.625rem","s":"1rem","t":"0.5rem","st":"0.25rem"},"transitions":{"ease-in":"cubic-bezier(0.32, 0, 0.67, 0)","ease-out":"cubic-bezier(0.33, 1, 0.68, 1)","ease-in-out":"cubic-bezier(0.65, 0, 0.35, 1)","duration":"250ms"},"breakpoints":{"xs":0,"sm":"576px","md":"768px","lg":"992px","xl":"1200px","xxl":"1400px"}}},"dark":{"theme":{"colors":{"greyscale-100":"#182536","greyscale-200":"#303C4B","greyscale-300":"#555F6B","greyscale-400":"#79818A","greyscale-500":"#9EA3AA","greyscale-600":"#C2C6CA","greyscale-700":"#E7E8EA","greyscale-800":"#F3F4F4","greyscale-900":"#FAFAFB","greyscale-000":"#0C1A2B","primary-100":"#3B4C62","primary-200":"#4D6481","primary-300":"#6381A6","primary-400":"#7FA5D5","primary-500":"#8CB5EA","primary-600":"#A3C4EE","primary-700":"#C3D8F4","primary-800":"#DDE9F8","primary-900":"#F4F8FD","success-100":"#EEF8D7","success-200":"#D9F1B2","success-300":"#BDE985","success-400":"#A0E25D","success-500":"#76D628","success-600":"#5BB520","success-700":"#43941A","success-800":"#307414","success-900":"#225D10","warning-100":"#F7F3D5","warning-200":"#F0E5AA","warning-300":"#E8D680","warning-400":"#E3C95F","warning-500":"#D9B32B","warning-600":"#BD9721","warning-700":"#9D7B1C","warning-800":"#7E6016","warning-900":"#684D12","danger-100":"#F8D0D0","danger-200":"#F09898","danger-300":"#F09898","danger-400":"#ED8585","danger-500":"#E96666","danger-600":"#DD6666","danger-700":"#C36666","danger-800":"#AE6666","danger-900":"#9D6666"}}}}};
|
||||||
|
|||||||
@@ -3,28 +3,95 @@
|
|||||||
@use "@openfun/cunningham-react/style";
|
@use "@openfun/cunningham-react/style";
|
||||||
@use "cunningham-tokens";
|
@use "cunningham-tokens";
|
||||||
|
|
||||||
:root {
|
|
||||||
font-family: Roboto, sans-serif;
|
// Reset
|
||||||
font-size: 16px;
|
h1 {
|
||||||
line-height: 24px;
|
font-family: var(--c--theme--font--families--accent);
|
||||||
font-weight: 400;
|
font-size: 4rem;
|
||||||
display: flex;
|
margin: 0;
|
||||||
align-items: center;
|
}
|
||||||
justify-content: center;
|
|
||||||
padding: 3rem;
|
p {
|
||||||
background-color: var(--c--theme--colors--greyscale-000);
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.center {
|
// App
|
||||||
display: flex;
|
html {
|
||||||
flex-direction: column;
|
min-height: 100vh;
|
||||||
align-items: center;
|
padding-bottom: 5rem;
|
||||||
padding: 2rem;
|
background: linear-gradient(153deg, var(--c--theme--colors--greyscale-100) 0%, var(--c--theme--colors--greyscale-000) 100%);
|
||||||
background-color: var(--c--theme--colors--greyscale-100);
|
}
|
||||||
border-radius: 1rem;
|
|
||||||
|
|
||||||
h1, h3 {
|
.pattern {
|
||||||
margin-bottom: 40px;
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
top: -200px;
|
||||||
|
left: -290px;
|
||||||
|
transform: rotate(335deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-switch {
|
||||||
|
position: fixed;
|
||||||
|
right: 1rem;
|
||||||
|
top: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: var(--c--theme--colors--greyscale-000);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px var(--c--theme--colors--greyscale-300) solid;
|
||||||
|
box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cunningham-theme--dark {
|
||||||
|
.card {
|
||||||
|
box-shadow: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin: auto;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
width: 1100px;
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
width: calc(100% - 2rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Home
|
||||||
|
.page__home {
|
||||||
|
&__title {
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin: 4rem 0;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create
|
||||||
|
.page__create {
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
margin: 4rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.5rem;
|
||||||
|
|
||||||
|
h3, h4 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2427,7 +2427,7 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b"
|
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b"
|
||||||
integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==
|
integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==
|
||||||
|
|
||||||
"@faker-js/faker@8.3.1":
|
"@faker-js/faker@8.3.1", "@faker-js/faker@^8.3.1":
|
||||||
version "8.3.1"
|
version "8.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-8.3.1.tgz#7753df0cb88d7649becf984a96dd1bd0a26f43e3"
|
resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-8.3.1.tgz#7753df0cb88d7649becf984a96dd1bd0a26f43e3"
|
||||||
integrity sha512-FdgpFxY6V6rLZE9mmIBb9hM0xpfvQOSNOLnzolzKwsE1DH+gC7lEKV1p1IbR0lAYyvYd5a4u3qWJzowUkw1bIw==
|
integrity sha512-FdgpFxY6V6rLZE9mmIBb9hM0xpfvQOSNOLnzolzKwsE1DH+gC7lEKV1p1IbR0lAYyvYd5a4u3qWJzowUkw1bIw==
|
||||||
|
|||||||
Reference in New Issue
Block a user