Skip to content

Commit

Permalink
Merge branch 'develop' into feature/add-nav-bar
Browse files Browse the repository at this point in the history
  • Loading branch information
Quiddlee authored Dec 28, 2023
2 parents c5a73fe + 39fe85d commit 069c9c2
Show file tree
Hide file tree
Showing 22 changed files with 8,685 additions and 14 deletions.
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ module.exports = {
'react/require-default-props': 0,
'import/no-extraneous-dependencies': 0,
'react/function-component-definition': 0,
'no-underscore-dangle': 0,
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
'sort-imports': ['error', {ignoreCase: true, ignoreDeclarationSort: true}],
'import/order': [
Expand Down
31 changes: 23 additions & 8 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
type-check:
name: Types
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v3
Expand All @@ -34,17 +35,31 @@ jobs:

- name: Check Application Types
run: npm run type-check

tests:
name: Test
prettify:
name: Prettier
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup Continuous integration
- name: Setup Continuous Integration
uses: ./.github/actions/ci-setup

- name: Check Application Types
run: npm run prettier:fix

# tests:
# name: Test
# runs-on: ubuntu-latest

# steps:
# - name: Checkout
# uses: actions/checkout@v3

# - name: Npm Clean Install
# run: npm ci

- name: test
run: npm run test
# - name: test
# run: npm run test
19 changes: 19 additions & 0 deletions src/components/DocsComp/DocsComp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import useSchemaExplorer from './lib/hooks/useSchemaExplorer';
import DocsModal from './ui/DocsModal';
import DocsOverlay from './ui/DocsOverlay';

type PropsType = {
setIsDocsShown: React.Dispatch<React.SetStateAction<boolean>>;
isShown: boolean;
};

const DocsComp = ({ isShown, setIsDocsShown }: PropsType) => {
const schemaExplorer = useSchemaExplorer();
return (
<DocsOverlay isShown={isShown} setIsDocsShown={setIsDocsShown} explorer={schemaExplorer}>
<DocsModal setIsDocsShown={setIsDocsShown} explorer={schemaExplorer} />
</DocsOverlay>
);
};

export default DocsComp;
32 changes: 32 additions & 0 deletions src/components/DocsComp/lib/helpers/getTypeName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { SchemaTypeFieldOfType } from '@/shared/types';

function getTypeName(type: SchemaTypeFieldOfType) {
if (type?.name) return type?.name;

const modifiers: string[] = [];

if (type?.kind === 'NON_NULL') modifiers.push('!');
if (type?.kind === 'LIST') modifiers.push('[]');

function getOfTypeName(argOfType: SchemaTypeFieldOfType): number | string {
if (argOfType?.name) {
return modifiers.push(argOfType.name);
}
if (argOfType?.kind === 'NON_NULL') modifiers.push('!');
if (argOfType?.kind === 'LIST') modifiers.push('[]');

return getOfTypeName(argOfType?.ofType as SchemaTypeFieldOfType);
}

getOfTypeName(type?.ofType as SchemaTypeFieldOfType);

const output = modifiers.reduceRight((acc, curr) => {
if (curr === '!') return `${acc}!`;
if (curr === '[]') return `[${acc}]`;
return acc + curr;
});

return output;
}

export default getTypeName;
12 changes: 12 additions & 0 deletions src/components/DocsComp/lib/helpers/separateString.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function separateString(inputString: string) {
const regex = /([^a-zA-Z]*)([a-zA-Z]+)([^a-zA-Z]*$)/;
const matches = inputString.match(regex);

if (matches) {
const [, beforeLetters, letters, afterLetters] = matches;
return [beforeLetters, letters, afterLetters];
}
return ['', inputString, ''];
}

export default separateString;
30 changes: 30 additions & 0 deletions src/components/DocsComp/lib/hooks/useSchemaExplorer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useState } from 'react';

function useSchemaExplorer() {
const [typeNames, setTypeNames] = useState(['Docs']);

function current() {
return typeNames[typeNames.length - 1];
}
function prev() {
return typeNames[typeNames.length - 2];
}
function next(elem: string) {
setTypeNames((prevEl) => [...prevEl, elem]);
}
function back() {
if (typeNames.length > 1) {
setTypeNames((prevEl) => prevEl.filter((_, i) => i < prevEl.length - 1));
}
}
function isDocs() {
return current() === 'Docs';
}
function setInitState() {
setTypeNames(['Docs']);
}

return { current, next, prev, isDocs, back, setInitState };
}

export default useSchemaExplorer;
16 changes: 16 additions & 0 deletions src/components/DocsComp/ui/BackDocsBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FC } from 'react';

import Icon from '@/shared/ui/Icon';

type PropsType = { onClick: () => void; title: string };

const BackDocsBtn: FC<PropsType> = ({ onClick, title }: PropsType) => {
return (
<button type="button" onClick={onClick} className="flex items-center gap-1 rounded-full p-2 hover:bg-slate-500/30">
<Icon>arrow_back_ios</Icon>
<span className="text-2xl">{title}</span>
</button>
);
};

export default BackDocsBtn;
16 changes: 16 additions & 0 deletions src/components/DocsComp/ui/CloseDocsBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FC } from 'react';

import Icon from '@/shared/ui/Icon';
import IconButton from '@/shared/ui/IconButton';

type PropsType = { onClick: () => void; className: string };

const CloseDocsBtn: FC<PropsType> = ({ onClick, className }) => {
return (
<IconButton onClick={onClick} className={className}>
<Icon>close</Icon>
</IconButton>
);
};

export default CloseDocsBtn;
40 changes: 40 additions & 0 deletions src/components/DocsComp/ui/DocsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// AFTER LOGIC FOR SAVING AND FETCHING ENDPOINT SHEMA WILL BE ADDED - MUST REMOVE SCHEMA IMPORT AND REPLACE IT FOR DOWNLOADED SCHEMA IN FURTHER CODE

import { Dispatch, SetStateAction } from 'react';

import { swapiSchema } from '@/shared/constants/schemaData';
import { DocsExplorerType, SchemaTypeObj } from '@/shared/types';
import CloseDocsBtn from '@components/DocsComp/ui/CloseDocsBtn';

import DocsRootComp from './DocsRootComp';
import DocsTypeComp from './DocsTypeComp';

type PropsType = {
setIsDocsShown: Dispatch<SetStateAction<boolean>>;
explorer: DocsExplorerType;
};

const DocsModal = ({ setIsDocsShown, explorer }: PropsType) => {
const content = explorer.isDocs() ? (
<DocsRootComp types={swapiSchema.data.__schema.types as SchemaTypeObj[]} explorer={explorer} />
) : (
<DocsTypeComp
explorer={explorer}
currType={swapiSchema.data.__schema.types.find((elem) => elem.name === explorer.current()) as SchemaTypeObj}
/>
);
return (
<section className="relative z-20 h-[100dvh] w-[420px] cursor-auto rounded-r-[28px] bg-surface p-3">
<CloseDocsBtn
onClick={() => {
setIsDocsShown((prev) => !prev);
explorer.setInitState();
}}
className="absolute right-[20px] top-[20px] z-20"
/>
{content}
</section>
);
};

export default DocsModal;
38 changes: 38 additions & 0 deletions src/components/DocsComp/ui/DocsOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
type PropsType = {
setIsDocsShown: React.Dispatch<React.SetStateAction<boolean>>;
isShown: boolean;
explorer: {
current: () => string;
next: (elem: string) => void;
prev: () => string;
isDocs: () => boolean;
back: () => void;
setInitState: () => void;
};
children: JSX.Element;
};

const DocsOverlay = ({ isShown, setIsDocsShown, explorer, children }: PropsType) => {
function closeHandler(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) {
if ((e.target as HTMLButtonElement).hasAttribute('data-overlay')) {
setIsDocsShown((prev) => !prev);
explorer.setInitState();
}
}
if (!isShown) {
return null;
}
return (
<button
data-testid="overlay"
data-overlay
type="button"
onClick={(e) => closeHandler(e)}
className="overlay absolute left-0 top-0 z-10 flex h-full w-full justify-start bg-black/60 "
>
{children}
</button>
);
};

export default DocsOverlay;
53 changes: 53 additions & 0 deletions src/components/DocsComp/ui/DocsRootComp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import useScrollbar from '@/shared/lib/hooks/useScrollbar';
import { DocsExplorerType, SchemaTypeObj } from '@/shared/types';

const DocsRootComp = ({ types, explorer }: { types: SchemaTypeObj[]; explorer: DocsExplorerType }) => {
function clinkHandler(e: React.MouseEvent<HTMLAnchorElement, MouseEvent>, typeName: string) {
e.preventDefault();
explorer.next(typeName);
}
const allTypes = types
.filter((type) => type.name[0] !== '_' && type.name[1] !== '_')
.map((type, i) => {
if (i > 0) {
return (
<li key={type.name}>
<a
className="text-docs-link-text-color hover:underline"
href={type.name}
onClick={(e) => clinkHandler(e, type.name)}
>
{type.name}
</a>
</li>
);
}
return null;
});
const rootRef = useScrollbar<HTMLDivElement>();
return (
<div ref={rootRef} className="h-full">
<div className="rounded-[24px] bg-surface-container px-10 py-[56px] text-left text-on-surface sm:px-[56px]">
<h3 className="text-[57px] font-[500]">Docs</h3>
<p className="text-md text-left">A GraphQL schema provides a root type for each kind of operation.</p>
</div>
<div className="mt-[56px] p-10 text-left font-[500] sm:px-[56px]">
<h4 className="text-[28px]">Root types:</h4>
<p className="mt-4">
query:&nbsp;
<a
className="text-docs-link-text-color hover:underline"
href={types[0].name}
onClick={(e) => clinkHandler(e, types[0].name)}
>
{types[0].name}
</a>
</p>
<h4 className="mt-[56px] text-[28px]">All schema types:</h4>
<ul className="mt-4">{allTypes}</ul>
</div>
</div>
);
};

export default DocsRootComp;
Loading

0 comments on commit 069c9c2

Please sign in to comment.