diff --git a/.env.example b/.env.example deleted file mode 100644 index 4ca0343..0000000 --- a/.env.example +++ /dev/null @@ -1,6 +0,0 @@ -VITE_GRAPHQL_SUPPORT_API=https://example.com/graphql -VITE_PAYMENT_API=https://example.com/payment/api -VITE_GRAPHQL_SUPPORT_SUBSCRIPTIONS_API=https://example.com/graphql -VITE_GRAPHQL_API=https://example.com/graphql -VITE_STRIPE_PUBLIC_KEY=STRIPE_PUBLIC_KEY -VITE_CLOUDINARY_URL=CLOUDINARY_URL \ No newline at end of file diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 82a9a73..0000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -.eslintrc.js \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index ac9efb0..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,65 +0,0 @@ -module.exports = { - extends: [ - 'airbnb-typescript', - 'airbnb/hooks', - 'plugin:jest/recommended', - 'plugin:prettier/recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:import/recommended' - ], - plugins: ['react', '@typescript-eslint', 'jest', 'prettier'], - env: { - browser: true, - es6: true, - jest: true, - }, - globals: { - Atomics: 'readonly', - SharedArrayBuffer: 'readonly', - }, - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - ecmaVersion: 2018, - sourceType: 'module', - project: './tsconfig.json', - }, - rules: { - 'no-console': 0, - 'no-nested-ternary': 'off', - 'no-unused-expressions': 'off', - '@typescript-eslint/no-unused-expressions': [ - 'warn', - { allowShortCircuit: true, allowTernary: true }, - ], - '@typescript-eslint/ban-ts-comment': 0, - 'react-hooks/exhaustive-deps': 1, - 'import/no-cycle': 'off', - 'react/jsx-props-no-spreading': 'off', - 'react/require-default-props': 0, - 'import/prefer-default-export': 'off', - 'import/no-extraneous-dependencies': 0, - 'no-prototype-builtins': 'off', - 'no-plusplus': 'off', - '@typescript-eslint/no-use-before-define': 'off', - '@typescript-eslint/no-non-null-asserted-optional-chain': 0, - '@typescript-eslint/no-non-null-assertion': 0, - 'react/prop-types': 'off', - 'react/react-in-jsx-scope': 'off', - 'react/self-closing-comp': 0, - 'react/no-array-index-key': 0, - '@typescript-eslint/camelcase': 'off', - '@typescript-eslint/explicit-function-return-type': 0, - '@typescript-eslint/explicit-module-boundary-types': 0, - '@typescript-eslint/no-explicit-any': 0, - 'linebreak-style': 'off', - 'prettier/prettier': [ - 'error', - { - endOfLine: 'auto', - }, - ], - }, -}; diff --git a/.gitignore b/.gitignore index 8f99cf5..f591aee 100644 --- a/.gitignore +++ b/.gitignore @@ -17,11 +17,9 @@ codegen-* # misc .DS_Store .env -.env.local -.env.development.local -.env.test.local -.env.production.local +.env.* npm-debug.log* yarn-debug.log* -yarn-error.log* \ No newline at end of file +yarn-error.log* +*storybook.log diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000..092f81a --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,20 @@ +import type { StorybookConfig } from '@storybook/react-vite'; + +const config: StorybookConfig = { + "stories": [ + "../src/**/*.mdx", + "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)" + ], + "addons": [ + "@storybook/addon-essentials", + "@storybook/addon-onboarding", + "@chromatic-com/storybook", + "@storybook/addon-interactions", + "@storybook/addon-themes" + ], + "framework": { + "name": "@storybook/react-vite", + "options": {} + } +}; +export default config; \ No newline at end of file diff --git a/.storybook/preview.ts b/.storybook/preview.ts new file mode 100644 index 0000000..5b87664 --- /dev/null +++ b/.storybook/preview.ts @@ -0,0 +1,30 @@ +import type { Preview } from '@storybook/react' + +import { ThemeProvider } from 'styled-components'; +import { withThemeFromJSXProvider } from '@storybook/addon-themes'; + +import { theme } from '../src/themes'; + +import GlobalStyles from '../src/components/GlobalStyles'; + +const preview: Preview = { + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + }, + + decorators: [withThemeFromJSXProvider({ + themes: { + theme, + }, + defaultTheme: 'theme', + Provider: ThemeProvider, + GlobalStyles, + })] +}; + +export default preview; diff --git a/README.md b/README.md deleted file mode 100644 index e08ad52..0000000 --- a/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Access Accounts for The Demo -1. Client -``` -- Email: client@client.cc -- Password: 123456 -``` -2. Product Owner -``` -- Email: po@po.cc -- Password: 123456 -``` -3. Developer -``` -- Email: dev@dev.cc -- Password: 123456 -``` -4. Admin -``` -- Email: admin@admin.cc -- Password: 123456 -``` - -# Installation -Check the `.env.example` for the list of APIs to use then clone and run - -``` -yarn -``` - -For the backend configuration check [here](https://github.com/MedAmineFouzai/astrobuild-api) diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..aaf69f9 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,35 @@ +import globals from 'globals'; +import pluginJs from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import pluginReact from 'eslint-plugin-react'; +import hooksPlugin from 'eslint-plugin-react-hooks'; +import prettier from 'eslint-plugin-prettier'; + +// TODO: Better understand and improve this config along with tsconfig. +/** @type {import('eslint').Linter.Config[]} */ +export default [ + { files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'] }, + { languageOptions: { globals: globals.browser } }, + pluginJs.configs.recommended, + ...tseslint.configs.recommended, + pluginReact.configs.flat.recommended, + { + plugins: { + prettier, + }, + rules: { + 'react/react-in-jsx-scope': 'off' + }, + settings: { + react: { + version: 'detect' + } + } + }, + { + plugins: { + 'react-hooks': hooksPlugin, + }, + rules: hooksPlugin.configs.recommended.rules, + } +]; diff --git a/index.html b/index.html deleted file mode 100644 index 46a45a0..0000000 --- a/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - Astrobuild - - - -
- - - diff --git a/package.json b/package.json index fa7f242..2956803 100644 --- a/package.json +++ b/package.json @@ -1,45 +1,14 @@ { "name": "astrobuild", - "version": "0.1.0", - "private": true, - "dependencies": { - "@apollo/client": "^3.7.10", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^14.0.0", - "@testing-library/user-event": "^14.4.3", - "@types/jest": "^29.5.0", - "@types/jwt-decode": "^3.1.0", - "@types/node": "^18.15.7", - "@types/react": "^18.0.29", - "@types/react-dom": "^18.0.11", - "@types/react-router-dom": "^5.3.3", - "@types/styled-components": "^5.1.26", - "formik": "^2.2.9", - "graphql": "^16.6.0", - "graphql-ws": "^5.13.1", - "jwt-decode": "^3.1.2", - "localforage": "^1.10.0", - "match-sorter": "^6.3.1", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-elastic-carousel": "^0.11.5", - "react-router-dom": "^6.9.0", - "react-to-print": "^2.14.12", - "reactflow": "^11.7.0", - "sort-by": "^1.2.0", - "styled-components": "^5.3.10", - "typescript": "^5.0.2", - "vite-plugin-svgr": "^2.4.0", - "web-vitals": "^3.3.0", - "yup": "^1.0.2" - }, + "version": "1.0.0", + "private": false, + "type": "module", "scripts": { - "start": "vite", "build": "vite build", - "generate:main": "graphql-codegen --config codegen-main.yml", - "lint": "yarn run eslint src --ext .ts,.tsx", - "fix": "yarn lint --fix", - "generate:support": "graphql-codegen --config codegen-support.ts" + "lint": "eslint src", + "format": "prettier -w src", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" }, "browserslist": { "production": [ @@ -54,24 +23,38 @@ ] }, "devDependencies": { - "@graphql-codegen/cli": "3.3.1", - "@graphql-codegen/client-preset": "3.0.1", - "@graphql-codegen/introspection": "3.0.1", - "@graphql-codegen/typescript": "^3.0.2", - "@graphql-codegen/typescript-operations": "^3.0.2", - "@typescript-eslint/eslint-plugin": "^5.56.0", - "@typescript-eslint/parser": "^5.56.0", + "@chromatic-com/storybook": "^3", + "@eslint/js": "^9.22.0", + "@storybook/addon-essentials": "^8.6.7", + "@storybook/addon-interactions": "^8.6.7", + "@storybook/addon-onboarding": "^8.6.7", + "@storybook/addon-themes": "^8.6.7", + "@storybook/blocks": "^8.6.7", + "@storybook/react": "^8.6.7", + "@storybook/react-vite": "^8.6.7", + "@storybook/test": "^8.6.7", + "@types/node": "^22.13.10", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", + "@types/styled-components": "^5.1.34", + "@typescript-eslint/eslint-plugin": "^8.26.1", + "@typescript-eslint/parser": "^8.26.1", "@vitejs/plugin-react": "^4.0.0", - "eslint-config-airbnb": "19.0.4", - "eslint-config-airbnb-typescript": "^17.0.0", - "eslint-config-prettier": "^8.8.0", - "eslint-plugin-import": "2.27.5", - "eslint-plugin-jest": "^27.2.1", - "eslint-plugin-jsx-a11y": "6.7.1", - "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-react": "7.32.2", - "eslint-plugin-react-hooks": "4.6.0", - "prettier": "^2.8.7", - "vite": "^4.2.1" + "eslint": "^9.22.0", + "eslint-config-prettier": "^10.1.1", + "eslint-plugin-prettier": "^5.2.3", + "eslint-plugin-react": "7.37.4", + "eslint-plugin-react-hooks": "5.2.0", + "eslint-plugin-storybook": "^0.11.5", + "globals": "^16.0.0", + "prettier": "^3.5.3", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "storybook": "^8.6.7", + "styled-components": "^6.1.15", + "typescript": "^5.8.2", + "typescript-eslint": "^8.26.1", + "vite": "^6.2.2", + "vite-plugin-svgr": "^4.3.0" } } diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index b069b88..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/logo192.png b/public/logo192.png deleted file mode 100644 index fc44b0a..0000000 Binary files a/public/logo192.png and /dev/null differ diff --git a/public/logo512.png b/public/logo512.png deleted file mode 100644 index a4e47a6..0000000 Binary files a/public/logo512.png and /dev/null differ diff --git a/public/manifest.json b/public/manifest.json deleted file mode 100644 index 080d6c7..0000000 --- a/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/public/robots.txt b/public/robots.txt deleted file mode 100644 index e9e57dc..0000000 --- a/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/screenshots/admin.png b/screenshots/admin.png deleted file mode 100755 index 3b82587..0000000 Binary files a/screenshots/admin.png and /dev/null differ diff --git a/screenshots/project.png b/screenshots/project.png deleted file mode 100755 index 88e689e..0000000 Binary files a/screenshots/project.png and /dev/null differ diff --git a/screenshots/prototype.png b/screenshots/prototype.png deleted file mode 100755 index f474d68..0000000 Binary files a/screenshots/prototype.png and /dev/null differ diff --git a/screenshots/support.png b/screenshots/support.png deleted file mode 100755 index 6f12a65..0000000 Binary files a/screenshots/support.png and /dev/null differ diff --git a/screenshots/template.png b/screenshots/template.png deleted file mode 100755 index 9e25d6b..0000000 Binary files a/screenshots/template.png and /dev/null differ diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index 0917687..0000000 --- a/src/App.tsx +++ /dev/null @@ -1,352 +0,0 @@ -import jwtDecode from 'jwt-decode'; -import { useEffect } from 'react'; -import { Routes, Route, Navigate } from 'react-router-dom'; -import { useLazyQuery, useReactiveVar } from '@apollo/client'; -import { Protected, Public, Navbar, Sidebar, Spinner } from './components'; -import { roleVar, tokenVar, userVar } from './graphql/state'; -import { - AdditionalInfo, - ForgotPassword, - Login, - RecoverAccount, - Signup, - Project, - Users, - Settings, - UserSettings, - CreateUser, - Template, - Feature, - Category, - Prototype, - AddCategory, - AddFeature, - AddTemplate, - CategorySettings, - FeatureSettings, - TemplateSettings, - AddProject, - UpdateProject, - Support, -} from './pages'; -import { GetUserByIdQuery, GetUserByIdQueryVariables } from './graphql/types'; -import { GET_USER_BY_ID } from './graphql/auth.api'; - -const App = () => { - const token = useReactiveVar(tokenVar); - const role = useReactiveVar(roleVar); - const currentUser = useReactiveVar(userVar); - - const [getUserById, { loading }] = useLazyQuery< - GetUserByIdQuery, - GetUserByIdQueryVariables - >(GET_USER_BY_ID, { - onCompleted({ getUserById: user }) { - userVar(user); - switch (user.role) { - case 'Client': - roleVar('client'); - break; - case 'ProductOwner': - roleVar('productOwner'); - break; - case 'Developer': - roleVar('developer'); - break; - case 'Admin': - roleVar('admin'); - break; - default: - break; - } - }, - }); - - useEffect(() => { - const localStorageToken = localStorage.getItem('token'); - - if (localStorageToken) { - const { id } = jwtDecode<{ id: string; role: string }>(localStorageToken); - - getUserById({ variables: { id } }); - tokenVar(localStorageToken); - } - }, []); - - return !loading ? ( - <> - {token && currentUser?.firstName && ( - <> - - - - )} - - - {role !== 'admin' ? ( - - ) : ( - - )} - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - -