From 00ab8308cd3d5fc9885f1378bf29b172d14a8804 Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 12:36:24 +0300 Subject: [PATCH 01/17] feat(search): init page #13 --- src/pages/index.tsx | 2 ++ src/pages/search/index.tsx | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/pages/search/index.tsx diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 6792721..1f2f323 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -5,6 +5,7 @@ import { Auth } from "features"; const HomePage = lazy(() => import("./home")); const RepositoryPage = lazy(() => import("./repository")); const UserPage = lazy(() => import("./user")); +const SearchPage = lazy(() => import("./search")); /** * Роутинг приложения @@ -12,6 +13,7 @@ const UserPage = lazy(() => import("./user")); const Routing = () => ( + diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx new file mode 100644 index 0000000..a869f8c --- /dev/null +++ b/src/pages/search/index.tsx @@ -0,0 +1,23 @@ +import React from "react"; +import { Row, Col } from "antd"; + +/** + * @page Search + */ +const SearchPage = () => { + return ( + + + Results by {'"---"'} search + + +
+
Repositories
+
User
+
+ +
+ ); +}; + +export default SearchPage; From 322363295a6ebcd23c79a735161db99ab7d05eac Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 13:34:57 +0300 Subject: [PATCH 02/17] feat(search): add search-req logic #13 --- src/features/repo-list/index.tsx | 2 + src/models.gen.ts | 87 ++++++++++++++++++++++++++++++-- src/pages/search/index.scss | 7 +++ src/pages/search/index.tsx | 77 ++++++++++++++++++++++++++-- src/pages/search/queries.gen.ts | 81 +++++++++++++++++++++++++++++ src/pages/search/queries.gql | 37 ++++++++++++++ 6 files changed, 283 insertions(+), 8 deletions(-) create mode 100644 src/pages/search/index.scss create mode 100644 src/pages/search/queries.gen.ts create mode 100644 src/pages/search/queries.gql diff --git a/src/features/repo-list/index.tsx b/src/features/repo-list/index.tsx index 9f47569..4063b9c 100644 --- a/src/features/repo-list/index.tsx +++ b/src/features/repo-list/index.tsx @@ -8,6 +8,8 @@ type Props = { username: string; }; +// FIXME: rename to UserRepoList? (coz - user as dep) + const RepoList = ({ username }: Props) => { const { data } = useReposQuery({ variables: { login: username }, diff --git a/src/models.gen.ts b/src/models.gen.ts index c4d13af..2a3a937 100644 --- a/src/models.gen.ts +++ b/src/models.gen.ts @@ -5188,6 +5188,7 @@ export type IssueAssigneesArgs = { /** An Issue is a place to discuss ideas, enhancements, tasks, and bugs for a project. */ export type IssueCommentsArgs = { + orderBy?: Maybe; after?: Maybe; before?: Maybe; first?: Maybe; @@ -5377,6 +5378,20 @@ export type IssueCommentEdge = { readonly node?: Maybe; }; +/** Ways in which lists of issue comments can be ordered upon return. */ +export type IssueCommentOrder = { + /** The field in which to order issue comments by. */ + readonly field: IssueCommentOrderField; + /** The direction in which to order issue comments by the specified field. */ + readonly direction: OrderDirection; +}; + +/** Properties by which issue comment connections can be ordered. */ +export enum IssueCommentOrderField { + /** Order issue comments by update time */ + UpdatedAt = 'UPDATED_AT' +} + /** The connection type for Issue. */ export type IssueConnection = { /** A list of edges. */ @@ -8945,11 +8960,17 @@ export type Organization = Node & Actor & PackageOwner & ProjectOwner & Reposito readonly descriptionHTML?: Maybe; /** The organization's public email. */ readonly email?: Maybe; + /** True if this user/organization has a GitHub Sponsors listing. */ + readonly hasSponsorsListing: Scalars['Boolean']; readonly id: Scalars['ID']; + /** The interaction ability settings for this organization. */ + readonly interactionAbility?: Maybe; /** The setting value for whether the organization has an IP allow list enabled. */ readonly ipAllowListEnabledSetting: IpAllowListEnabledSettingValue; /** The IP addresses that are allowed to access resources owned by the organization. */ readonly ipAllowListEntries: IpAllowListEntryConnection; + /** True if the viewer is sponsored by this user/organization. */ + readonly isSponsoringViewer: Scalars['Boolean']; /** Whether the organization has verified its profile email and website, always false on Enterprise. */ readonly isVerified: Scalars['Boolean']; /** Showcases a selection of repositories and gists that the profile owner has either curated or that have been selected automatically based on popularity. */ @@ -8998,7 +9019,7 @@ export type Organization = Node & Actor & PackageOwner & ProjectOwner & Reposito readonly resourcePath: Scalars['URI']; /** The Organization's SAML identity providers */ readonly samlIdentityProvider?: Maybe; - /** The GitHub Sponsors listing for this user. */ + /** The GitHub Sponsors listing for this user or organization. */ readonly sponsorsListing?: Maybe; /** This object's sponsorships as the maintainer. */ readonly sponsorshipsAsMaintainer: SponsorshipConnection; @@ -9028,8 +9049,12 @@ export type Organization = Node & Actor & PackageOwner & ProjectOwner & Reposito readonly viewerCanCreateRepositories: Scalars['Boolean']; /** Viewer can create teams on this organization. */ readonly viewerCanCreateTeams: Scalars['Boolean']; + /** Whether or not the viewer is able to sponsor this user/organization. */ + readonly viewerCanSponsor: Scalars['Boolean']; /** Viewer is an active member of this organization. */ readonly viewerIsAMember: Scalars['Boolean']; + /** True if the viewer is sponsoring this user/organization. */ + readonly viewerIsSponsoring: Scalars['Boolean']; /** The organization's public profile URL. */ readonly websiteUrl?: Maybe; }; @@ -10488,6 +10513,7 @@ export type PullRequestAssigneesArgs = { /** A repository pull request. */ export type PullRequestCommentsArgs = { + orderBy?: Maybe; after?: Maybe; before?: Maybe; first?: Maybe; @@ -13362,6 +13388,8 @@ export type Repository = Node & ProjectOwner & PackageOwner & Subscribable & Sta /** The repository's URL. */ readonly homepageUrl?: Maybe; readonly id: Scalars['ID']; + /** The interaction ability settings for this repository. */ + readonly interactionAbility?: Maybe; /** Indicates if the repository is unmaintained. */ readonly isArchived: Scalars['Boolean']; /** Returns true if blank issue creation is allowed */ @@ -13963,6 +13991,38 @@ export type RepositoryInfoShortDescriptionHtmlArgs = { limit?: Maybe; }; +/** Repository interaction limit that applies to this object. */ +export type RepositoryInteractionAbility = { + /** The time the currently active limit expires. */ + readonly expiresAt?: Maybe; + /** The current limit that is enabled on this object. */ + readonly limit: RepositoryInteractionLimit; + /** The origin of the currently active interaction limit. */ + readonly origin: RepositoryInteractionLimitOrigin; +}; + +/** A repository interaction limit. */ +export enum RepositoryInteractionLimit { + /** Users that have recently created their account will be unable to interact with the repository. */ + ExistingUsers = 'EXISTING_USERS', + /** Users that have not previously committed to a repository’s default branch will be unable to interact with the repository. */ + ContributorsOnly = 'CONTRIBUTORS_ONLY', + /** Users that are not collaborators will not be able to interact with the repository. */ + CollaboratorsOnly = 'COLLABORATORS_ONLY', + /** No interaction limits are enabled. */ + NoLimit = 'NO_LIMIT' +} + +/** Indicates where an interaction limit is configured. */ +export enum RepositoryInteractionLimitOrigin { + /** A limit that is configured at the repository level. */ + Repository = 'REPOSITORY', + /** A limit that is configured at the organization level. */ + Organization = 'ORGANIZATION', + /** A limit that is configured at the user-wide level. */ + User = 'USER' +} + /** An invitation for a user to be added to a repository. */ export type RepositoryInvitation = Node & { /** The email address that received the invitation. */ @@ -14895,12 +14955,20 @@ export type Sponsor = Organization | User; /** Entities that can be sponsored through GitHub Sponsors */ export type Sponsorable = { - /** The GitHub Sponsors listing for this user. */ + /** True if this user/organization has a GitHub Sponsors listing. */ + readonly hasSponsorsListing: Scalars['Boolean']; + /** True if the viewer is sponsored by this user/organization. */ + readonly isSponsoringViewer: Scalars['Boolean']; + /** The GitHub Sponsors listing for this user or organization. */ readonly sponsorsListing?: Maybe; /** This object's sponsorships as the maintainer. */ readonly sponsorshipsAsMaintainer: SponsorshipConnection; /** This object's sponsorships as the sponsor. */ readonly sponsorshipsAsSponsor: SponsorshipConnection; + /** Whether or not the viewer is able to sponsor this user/organization. */ + readonly viewerCanSponsor: Scalars['Boolean']; + /** True if the viewer is sponsoring this user/organization. */ + readonly viewerIsSponsoring: Scalars['Boolean']; }; @@ -15046,7 +15114,7 @@ export type Sponsorship = Node & { * @deprecated `Sponsorship.sponsor` will be removed. Use `Sponsorship.sponsorEntity` instead. Removal on 2020-10-01 UTC. */ readonly sponsor?: Maybe; - /** The user or organization that is sponsoring. Returns null if the sponsorship is private. */ + /** The user or organization that is sponsoring, if you have permission to view them. */ readonly sponsorEntity?: Maybe; /** The entity that is being sponsored */ readonly sponsorable: Sponsorable; @@ -17497,9 +17565,13 @@ export type User = Node & Actor & PackageOwner & ProjectOwner & RepositoryOwner readonly gistComments: GistCommentConnection; /** A list of the Gists the user has created. */ readonly gists: GistConnection; + /** True if this user/organization has a GitHub Sponsors listing. */ + readonly hasSponsorsListing: Scalars['Boolean']; /** The hovercard information for this user in a given context */ readonly hovercard: Hovercard; readonly id: Scalars['ID']; + /** The interaction ability settings for this user. */ + readonly interactionAbility?: Maybe; /** Whether or not this user is a participant in the GitHub Security Bug Bounty. */ readonly isBountyHunter: Scalars['Boolean']; /** Whether or not this user is a participant in the GitHub Campus Experts Program. */ @@ -17512,6 +17584,8 @@ export type User = Node & Actor & PackageOwner & ProjectOwner & RepositoryOwner readonly isHireable: Scalars['Boolean']; /** Whether or not this user is a site administrator. */ readonly isSiteAdmin: Scalars['Boolean']; + /** True if the viewer is sponsored by this user/organization. */ + readonly isSponsoringViewer: Scalars['Boolean']; /** Whether or not this user is the viewing user. */ readonly isViewer: Scalars['Boolean']; /** A list of issue comments made by this user. */ @@ -17562,7 +17636,7 @@ export type User = Node & Actor & PackageOwner & ProjectOwner & RepositoryOwner readonly resourcePath: Scalars['URI']; /** Replies this user has saved */ readonly savedReplies?: Maybe; - /** The GitHub Sponsors listing for this user. */ + /** The GitHub Sponsors listing for this user or organization. */ readonly sponsorsListing?: Maybe; /** This object's sponsorships as the maintainer. */ readonly sponsorshipsAsMaintainer: SponsorshipConnection; @@ -17586,8 +17660,12 @@ export type User = Node & Actor & PackageOwner & ProjectOwner & RepositoryOwner readonly viewerCanCreateProjects: Scalars['Boolean']; /** Whether or not the viewer is able to follow the user. */ readonly viewerCanFollow: Scalars['Boolean']; + /** Whether or not the viewer is able to sponsor this user/organization. */ + readonly viewerCanSponsor: Scalars['Boolean']; /** Whether or not this user is followed by the viewer. */ readonly viewerIsFollowing: Scalars['Boolean']; + /** True if the viewer is sponsoring this user/organization. */ + readonly viewerIsSponsoring: Scalars['Boolean']; /** A list of repositories the given user is watching. */ readonly watching: RepositoryConnection; /** A URL pointing to the user's public website/blog. */ @@ -17676,6 +17754,7 @@ export type UserHovercardArgs = { /** A user is an individual's account on GitHub that owns repositories and can make new content. */ export type UserIssueCommentsArgs = { + orderBy?: Maybe; after?: Maybe; before?: Maybe; first?: Maybe; diff --git a/src/pages/search/index.scss b/src/pages/search/index.scss new file mode 100644 index 0000000..327f3bc --- /dev/null +++ b/src/pages/search/index.scss @@ -0,0 +1,7 @@ +.page-search { + .result__item { + background: var(--clr-gray--100); + border-radius: 10px; + box-shadow: 0 5px 0 var(--clr-primary--active); + } +} diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx index a869f8c..4a104c3 100644 --- a/src/pages/search/index.tsx +++ b/src/pages/search/index.tsx @@ -1,16 +1,85 @@ import React from "react"; -import { Row, Col } from "antd"; +import { Row, Col, Skeleton } from "antd"; +import { HeartFilled, HeartOutlined } from "@ant-design/icons"; +import dayjs from "dayjs"; +import { SearchType } from "models"; +import { useSearchQuery, RepoFieldsFragment } from "./queries.gen"; +import "./index.scss"; /** * @page Search */ const SearchPage = () => { + const type = SearchType.Repository; + const query = "commitlint"; + const { data, loading } = useSearchQuery({ + variables: { type, query }, + }); + + const isEmpty = !loading && (!data || data.search.edges?.length === 0); + return ( - - Results by {'"---"'} search + +
+ Results by {query} search +
+
+ {loading && ( + <> + + + + + )} + {data?.search.edges?.map((edge) => { + // !!! FIXME: specify types + if (type === SearchType.Repository) { + const { + id, + name, + owner, + updatedAt, + viewerHasStarred, + primaryLanguage, + } = edge?.node as RepoFieldsFragment; + const color = primaryLanguage?.color || "#222"; + return ( +
+

+
+ {owner.login}/{name} +
+
+ {viewerHasStarred ? : } +
+

+
+
+
+ {primaryLanguage?.name} +
+
+
+ Updated on {dayjs(updatedAt).format("D MMM YYYY")} +
+
+ ); + } + return "???"; + })} + {isEmpty && "Not found anything"} +
- +
Repositories
User
diff --git a/src/pages/search/queries.gen.ts b/src/pages/search/queries.gen.ts new file mode 100644 index 0000000..ef410ba --- /dev/null +++ b/src/pages/search/queries.gen.ts @@ -0,0 +1,81 @@ +/** @generated THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. */ +import * as Types from '../../models.gen'; + +import { gql } from '@apollo/client'; +import * as Apollo from '@apollo/client'; +export type RepoFieldsFragment = { readonly id: string, readonly name: string, readonly updatedAt: any, readonly viewerHasStarred: boolean, readonly owner: { readonly login: string } | { readonly login: string }, readonly primaryLanguage?: Types.Maybe<{ readonly name: string, readonly color?: Types.Maybe }> }; + +export type UserFieldsFragment = { readonly id: string, readonly login: string, readonly bio?: Types.Maybe, readonly avatarUrl: any, readonly viewerIsFollowing: boolean }; + +export type SearchQueryVariables = Types.Exact<{ + query: Types.Scalars['String']; + type: Types.SearchType; +}>; + + +export type SearchQuery = { readonly search: { readonly edges?: Types.Maybe }>>> } }; + +export const RepoFieldsFragmentDoc = gql` + fragment RepoFields on Repository { + id + owner { + login + } + name + updatedAt + primaryLanguage { + name + color + } + viewerHasStarred +} + `; +export const UserFieldsFragmentDoc = gql` + fragment UserFields on User { + id + login + bio + avatarUrl + viewerIsFollowing +} + `; +export const SearchDocument = gql` + query Search($query: String!, $type: SearchType!) { + search(query: $query, type: $type, first: 50) { + edges { + node { + ...RepoFields + ...UserFields + } + } + } +} + ${RepoFieldsFragmentDoc} +${UserFieldsFragmentDoc}`; + +/** + * __useSearchQuery__ + * + * To run a query within a React component, call `useSearchQuery` and pass it any options that fit your needs. + * When your component renders, `useSearchQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useSearchQuery({ + * variables: { + * query: // value for 'query' + * type: // value for 'type' + * }, + * }); + */ +export function useSearchQuery(baseOptions?: Apollo.QueryHookOptions) { + return Apollo.useQuery(SearchDocument, baseOptions); + } +export function useSearchLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + return Apollo.useLazyQuery(SearchDocument, baseOptions); + } +export type SearchQueryHookResult = ReturnType; +export type SearchLazyQueryHookResult = ReturnType; +export type SearchQueryResult = Apollo.QueryResult; \ No newline at end of file diff --git a/src/pages/search/queries.gql b/src/pages/search/queries.gql new file mode 100644 index 0000000..5104978 --- /dev/null +++ b/src/pages/search/queries.gql @@ -0,0 +1,37 @@ +enum SearchType { + REPOSITORY + USER +} + +fragment RepoFields on Repository { + id + owner { + login + } + name + updatedAt + primaryLanguage { + name + color + } + viewerHasStarred +} + +fragment UserFields on User { + id + login + bio + avatarUrl + viewerIsFollowing +} + +query Search($query: String!, $type: SearchType!) { + search(query: $query, type: $type, first: 50) { + edges { + node { + ...RepoFields + ...UserFields + } + } + } +} From e8aaf0938d81cf96db17a70711d8ed84e1d67736 Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 14:05:08 +0300 Subject: [PATCH 03/17] refactor(search): move repo-item to shared #13 --- src/features/repo-list/index.tsx | 6 +++--- src/shared/components/.gitkeep | 0 src/shared/components/index.ts | 1 + .../components/repo}/fav-btn/heart_active.svg | 0 .../repo}/fav-btn/heart_default.svg | 0 .../components/repo}/fav-btn/index.tsx | 0 .../components/repo}/index.scss | 2 +- .../components/repo}/index.tsx | 21 +++++++++++-------- 8 files changed, 17 insertions(+), 13 deletions(-) delete mode 100644 src/shared/components/.gitkeep create mode 100644 src/shared/components/index.ts rename src/{features/repo-list/repo-item => shared/components/repo}/fav-btn/heart_active.svg (100%) rename src/{features/repo-list/repo-item => shared/components/repo}/fav-btn/heart_default.svg (100%) rename src/{features/repo-list/repo-item => shared/components/repo}/fav-btn/index.tsx (100%) rename src/{features/repo-list/repo-item => shared/components/repo}/index.scss (98%) rename src/{features/repo-list/repo-item => shared/components/repo}/index.tsx (53%) diff --git a/src/features/repo-list/index.tsx b/src/features/repo-list/index.tsx index 4063b9c..ebb0692 100644 --- a/src/features/repo-list/index.tsx +++ b/src/features/repo-list/index.tsx @@ -1,7 +1,7 @@ import React from "react"; +import { Repo } from "shared/components"; import { useReposQuery } from "./queries.gen"; import Tab from "./tab"; -import RepoItem from "./repo-item"; import "./index.scss"; type Props = { @@ -21,9 +21,9 @@ const RepoList = ({ username }: Props) => {
- {data?.user?.repositories.edges?.map((edge) => ( + {data?.user?.repositories.edges?.map((edge, index) => ( // FIXME: destruct more elegant later - + ))}
diff --git a/src/shared/components/.gitkeep b/src/shared/components/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/shared/components/index.ts b/src/shared/components/index.ts new file mode 100644 index 0000000..52191de --- /dev/null +++ b/src/shared/components/index.ts @@ -0,0 +1 @@ +export { default as Repo } from "./repo"; diff --git a/src/features/repo-list/repo-item/fav-btn/heart_active.svg b/src/shared/components/repo/fav-btn/heart_active.svg similarity index 100% rename from src/features/repo-list/repo-item/fav-btn/heart_active.svg rename to src/shared/components/repo/fav-btn/heart_active.svg diff --git a/src/features/repo-list/repo-item/fav-btn/heart_default.svg b/src/shared/components/repo/fav-btn/heart_default.svg similarity index 100% rename from src/features/repo-list/repo-item/fav-btn/heart_default.svg rename to src/shared/components/repo/fav-btn/heart_default.svg diff --git a/src/features/repo-list/repo-item/fav-btn/index.tsx b/src/shared/components/repo/fav-btn/index.tsx similarity index 100% rename from src/features/repo-list/repo-item/fav-btn/index.tsx rename to src/shared/components/repo/fav-btn/index.tsx diff --git a/src/features/repo-list/repo-item/index.scss b/src/shared/components/repo/index.scss similarity index 98% rename from src/features/repo-list/repo-item/index.scss rename to src/shared/components/repo/index.scss index 7daff1c..6c72739 100644 --- a/src/features/repo-list/repo-item/index.scss +++ b/src/shared/components/repo/index.scss @@ -1,4 +1,4 @@ -.repo-item { +.repo { display: inline-flex; justify-content: space-between; width: 100%; diff --git a/src/features/repo-list/repo-item/index.tsx b/src/shared/components/repo/index.tsx similarity index 53% rename from src/features/repo-list/repo-item/index.tsx rename to src/shared/components/repo/index.tsx index f54d441..4cf2870 100644 --- a/src/features/repo-list/repo-item/index.tsx +++ b/src/shared/components/repo/index.tsx @@ -1,28 +1,31 @@ import React from "react"; import dayjs from "dayjs"; +import { Repository } from "models"; import FavBtn from "./fav-btn"; import "./index.scss"; // !!! FIXME: specify types type Props = any; -const RepoItem = (props: Props) => { - const { name, primaryLanguage, updatedAt, url, viewerHasStarred } = props; - const hex = primaryLanguage?.color; +const Repo = (props: Props) => { + const { name, primaryLanguage, updatedAt, url, viewerHasStarred } = props as Partial< + Repository + >; + const hex = primaryLanguage?.color || "#222"; return ( -
-
+
+
{/* FIXME: hardcoded, replace to generation by {username}/{reponame} */} - {name} -
+ {name} +
{primaryLanguage?.name} Updated on {dayjs(updatedAt).format("D MMM YYYY")}
- + {viewerHasStarred !== undefined && }
); }; -export default RepoItem; +export default Repo; From c8c0238cb887c26fe0b6e608371096eb42361c24 Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 14:06:03 +0300 Subject: [PATCH 04/17] feat(search): use shared#repo-item in search page #13 --- src/pages/search/index.scss | 1 - src/pages/search/index.tsx | 47 +++++++-------------------------- src/pages/search/queries.gen.ts | 6 ++--- src/pages/search/queries.gql | 4 +-- 4 files changed, 12 insertions(+), 46 deletions(-) diff --git a/src/pages/search/index.scss b/src/pages/search/index.scss index 327f3bc..c47e24a 100644 --- a/src/pages/search/index.scss +++ b/src/pages/search/index.scss @@ -1,6 +1,5 @@ .page-search { .result__item { - background: var(--clr-gray--100); border-radius: 10px; box-shadow: 0 5px 0 var(--clr-primary--active); } diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx index 4a104c3..465bd00 100644 --- a/src/pages/search/index.tsx +++ b/src/pages/search/index.tsx @@ -1,7 +1,6 @@ import React from "react"; import { Row, Col, Skeleton } from "antd"; -import { HeartFilled, HeartOutlined } from "@ant-design/icons"; -import dayjs from "dayjs"; +import { Repo } from "shared/components"; import { SearchType } from "models"; import { useSearchQuery, RepoFieldsFragment } from "./queries.gen"; import "./index.scss"; @@ -35,43 +34,11 @@ const SearchPage = () => { {data?.search.edges?.map((edge) => { // !!! FIXME: specify types if (type === SearchType.Repository) { - const { - id, - name, - owner, - updatedAt, - viewerHasStarred, - primaryLanguage, - } = edge?.node as RepoFieldsFragment; - const color = primaryLanguage?.color || "#222"; + const data = edge?.node as RepoFieldsFragment; return ( -
-

-
- {owner.login}/{name} -
-
- {viewerHasStarred ? : } -
-

-
-
-
- {primaryLanguage?.name} -
-
-
- Updated on {dayjs(updatedAt).format("D MMM YYYY")} -
-
+ + + ); } return "???"; @@ -89,4 +56,8 @@ const SearchPage = () => { ); }; +const ResultItem = ({ children }: PropsWithChildren) => ( +
{children}
+); + export default SearchPage; diff --git a/src/pages/search/queries.gen.ts b/src/pages/search/queries.gen.ts index ef410ba..3e7a63f 100644 --- a/src/pages/search/queries.gen.ts +++ b/src/pages/search/queries.gen.ts @@ -3,7 +3,7 @@ import * as Types from '../../models.gen'; import { gql } from '@apollo/client'; import * as Apollo from '@apollo/client'; -export type RepoFieldsFragment = { readonly id: string, readonly name: string, readonly updatedAt: any, readonly viewerHasStarred: boolean, readonly owner: { readonly login: string } | { readonly login: string }, readonly primaryLanguage?: Types.Maybe<{ readonly name: string, readonly color?: Types.Maybe }> }; +export type RepoFieldsFragment = { readonly id: string, readonly name: string, readonly url: any, readonly updatedAt: any, readonly viewerHasStarred: boolean, readonly primaryLanguage?: Types.Maybe<{ readonly name: string, readonly color?: Types.Maybe }> }; export type UserFieldsFragment = { readonly id: string, readonly login: string, readonly bio?: Types.Maybe, readonly avatarUrl: any, readonly viewerIsFollowing: boolean }; @@ -18,10 +18,8 @@ export type SearchQuery = { readonly search: { readonly edges?: Types.Maybe Date: Wed, 18 Nov 2020 14:11:03 +0300 Subject: [PATCH 05/17] feat(search): add owner in title of repo-result #13 --- src/pages/search/index.tsx | 2 +- src/pages/search/queries.gen.ts | 5 ++++- src/pages/search/queries.gql | 3 +++ src/shared/components/repo/index.tsx | 8 ++++++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx index 465bd00..d7c3fb5 100644 --- a/src/pages/search/index.tsx +++ b/src/pages/search/index.tsx @@ -10,7 +10,7 @@ import "./index.scss"; */ const SearchPage = () => { const type = SearchType.Repository; - const query = "commitlint"; + const query = "react"; const { data, loading } = useSearchQuery({ variables: { type, query }, }); diff --git a/src/pages/search/queries.gen.ts b/src/pages/search/queries.gen.ts index 3e7a63f..be81711 100644 --- a/src/pages/search/queries.gen.ts +++ b/src/pages/search/queries.gen.ts @@ -3,7 +3,7 @@ import * as Types from '../../models.gen'; import { gql } from '@apollo/client'; import * as Apollo from '@apollo/client'; -export type RepoFieldsFragment = { readonly id: string, readonly name: string, readonly url: any, readonly updatedAt: any, readonly viewerHasStarred: boolean, readonly primaryLanguage?: Types.Maybe<{ readonly name: string, readonly color?: Types.Maybe }> }; +export type RepoFieldsFragment = { readonly id: string, readonly name: string, readonly url: any, readonly updatedAt: any, readonly viewerHasStarred: boolean, readonly owner: { readonly login: string } | { readonly login: string }, readonly primaryLanguage?: Types.Maybe<{ readonly name: string, readonly color?: Types.Maybe }> }; export type UserFieldsFragment = { readonly id: string, readonly login: string, readonly bio?: Types.Maybe, readonly avatarUrl: any, readonly viewerIsFollowing: boolean }; @@ -20,6 +20,9 @@ export const RepoFieldsFragmentDoc = gql` id name url + owner { + login + } updatedAt primaryLanguage { name diff --git a/src/pages/search/queries.gql b/src/pages/search/queries.gql index 7bac2c6..71473fe 100644 --- a/src/pages/search/queries.gql +++ b/src/pages/search/queries.gql @@ -7,6 +7,9 @@ fragment RepoFields on Repository { id name url + owner { + login + } updatedAt primaryLanguage { name diff --git a/src/shared/components/repo/index.tsx b/src/shared/components/repo/index.tsx index 4cf2870..911253d 100644 --- a/src/shared/components/repo/index.tsx +++ b/src/shared/components/repo/index.tsx @@ -1,6 +1,7 @@ import React from "react"; import dayjs from "dayjs"; import { Repository } from "models"; +// FIXME: replace to ant.design icons import FavBtn from "./fav-btn"; import "./index.scss"; @@ -8,7 +9,7 @@ import "./index.scss"; type Props = any; const Repo = (props: Props) => { - const { name, primaryLanguage, updatedAt, url, viewerHasStarred } = props as Partial< + const { name, primaryLanguage, updatedAt, url, viewerHasStarred, owner } = props as Partial< Repository >; const hex = primaryLanguage?.color || "#222"; @@ -17,7 +18,10 @@ const Repo = (props: Props) => {
{/* FIXME: hardcoded, replace to generation by {username}/{reponame} */} - {name} + + {owner?.login && `${owner.login}/`} + {name} +
{primaryLanguage?.name} Updated on {dayjs(updatedAt).format("D MMM YYYY")} From baf65d3b664efb725a2da45961a864a5dd942630 Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 14:22:58 +0300 Subject: [PATCH 06/17] feat(search): add query-params usage #13 --- package-lock.json | 19 ++++++++++++++++--- package.json | 5 +++-- src/features/auth/router/index.tsx | 24 ++++++++++++++---------- src/pages/search/index.tsx | 5 +++-- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1515c15..5832519 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16229,9 +16229,9 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { - "version": "6.13.6", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.6.tgz", - "integrity": "sha512-/WWZ7d9na6s2wMEGdVCVgKWE9Rt7nYyNIf7k8xmHXcesPMlEzicWo3lbYwHyA4wBktI2KrXxxZeACLbE84hvSQ==", + "version": "6.13.7", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.7.tgz", + "integrity": "sha512-CsGs8ZYb39zu0WLkeOhe0NMePqgYdAuCqxOYKDR5LVCytDZYMGx3Bb+xypvQvPHVPijRXB0HZNFllCzHRe4gEA==", "requires": { "decode-uri-component": "^0.2.0", "split-on-first": "^1.0.0", @@ -18222,6 +18222,11 @@ "randombytes": "^2.1.0" } }, + "serialize-query-params": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/serialize-query-params/-/serialize-query-params-1.2.4.tgz", + "integrity": "sha512-m4hGkOY5y+ksPDSEkw12cNxt3HRUJv5G6oF9/4yq+GCw4LznudxC73qnz++VTHqXa0j1x1/iaBIpoiMBxr6w2w==" + }, "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -20674,6 +20679,14 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, + "use-query-params": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/use-query-params/-/use-query-params-1.1.9.tgz", + "integrity": "sha512-WAJ1GrKbFWv1TBn1RQpHqAwC7yyJsLaJjBhIfefrbY/h6mFSngzBQKirJndYwCS1ry77EwhpR/tQi5iovXWvuw==", + "requires": { + "serialize-query-params": "^1.2.3" + } + }, "utf-8-validate": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.2.tgz", diff --git a/package.json b/package.json index ae66be2..5d76814 100644 --- a/package.json +++ b/package.json @@ -19,14 +19,15 @@ "graphql": "^15.3.0", "node-sass": "^4.14.1", "normalize.css": "^8.0.1", - "query-string": "^6.13.6", + "query-string": "^6.13.7", "react": "^16.14.0", "react-dom": "^16.14.0", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "react-scripts": "3.4.3", "tailwindcss": "^1.9.5", - "typescript": "^3.7.5" + "typescript": "^3.7.5", + "use-query-params": "^1.1.9" }, "scripts": { "start": "react-scripts start", diff --git a/src/features/auth/router/index.tsx b/src/features/auth/router/index.tsx index 27cb192..dbaa195 100644 --- a/src/features/auth/router/index.tsx +++ b/src/features/auth/router/index.tsx @@ -1,5 +1,6 @@ import React, { lazy, Suspense } from "react"; import { BrowserRouter, Route, Switch } from "react-router-dom"; +import { QueryParamProvider } from "use-query-params"; import { Spin } from "antd"; import { useAuth } from "../hooks"; @@ -16,16 +17,19 @@ const Router = ({ children }: Props) => { return ( }> - - {isAuth && children} - {!isAuth && ( - <> - - - {/* */} - - )} - + {/* FIXME: wrap not on this level */} + + + {isAuth && children} + {!isAuth && ( + <> + + + {/* */} + + )} + + ); diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx index d7c3fb5..400cf38 100644 --- a/src/pages/search/index.tsx +++ b/src/pages/search/index.tsx @@ -1,5 +1,6 @@ import React from "react"; import { Row, Col, Skeleton } from "antd"; +import { useQueryParam, StringParam } from "use-query-params"; import { Repo } from "shared/components"; import { SearchType } from "models"; import { useSearchQuery, RepoFieldsFragment } from "./queries.gen"; @@ -10,9 +11,9 @@ import "./index.scss"; */ const SearchPage = () => { const type = SearchType.Repository; - const query = "react"; + const [query] = useQueryParam("q", StringParam); const { data, loading } = useSearchQuery({ - variables: { type, query }, + variables: { type, query: query || "" }, }); const isEmpty = !loading && (!data || data.search.edges?.length === 0); From 233228759b6ff8813f72f0ce86c4dc7237cd7898 Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 14:37:57 +0300 Subject: [PATCH 07/17] feat(search): add header-search-input logic with redirecting #13 --- src/app/header/index.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/app/header/index.tsx b/src/app/header/index.tsx index e8e8c22..d50725e 100644 --- a/src/app/header/index.tsx +++ b/src/app/header/index.tsx @@ -1,11 +1,16 @@ import React from "react"; import { Layout, Input } from "antd"; +import * as qs from "query-string"; import { Auth } from "features"; import ImgLogo from "./logo.png"; import "./index.scss"; const Header = () => { const { isAuth } = Auth.useAuth(); + // !!! FIXME: limit scope of query-params literals + // TODO: (wrap in QueryParamProvider) - wrap app with header instead of only content? + // const [search] = useQueryParam("q", StringParam); + const search = (qs.parse(window.location.search).q as string) || ""; return ( @@ -15,7 +20,19 @@ const Header = () => { logo {!isAuth && GITHUB-CLIENT} - {isAuth && } + {isAuth && ( + { + if (key === "Enter") { + // @ts-ignore FIXME: specify types + window.location.replace(`/search?q=${target.value}`); + } + }} + /> + )}
From 3a8feaff90607aee43fd4516fffc3a4d46b16132 Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 15:10:50 +0300 Subject: [PATCH 08/17] feat(search): add user-item rendering + connect query to search-page #13 --- src/pages/search/index.scss | 12 ++++- src/pages/search/index.tsx | 63 +++++++++++++++++++-------- src/shared/components/index.ts | 1 + src/shared/components/user/index.scss | 4 ++ src/shared/components/user/index.tsx | 32 ++++++++++++++ 5 files changed, 93 insertions(+), 19 deletions(-) create mode 100644 src/shared/components/user/index.scss create mode 100644 src/shared/components/user/index.tsx diff --git a/src/pages/search/index.scss b/src/pages/search/index.scss index c47e24a..4f2ff6d 100644 --- a/src/pages/search/index.scss +++ b/src/pages/search/index.scss @@ -1,6 +1,16 @@ .page-search { .result__item { + user-select: none; border-radius: 10px; - box-shadow: 0 5px 0 var(--clr-primary--active); + box-shadow: 0 5px 0 var(--clr-gray--900); + transition: var(--transition); + + &:hover { + box-shadow: 0 5px 0 var(--clr-primary--hover); + } + + &:active { + box-shadow: 0 5px 0 var(--clr-primary--active); + } } } diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx index 400cf38..4e761a4 100644 --- a/src/pages/search/index.tsx +++ b/src/pages/search/index.tsx @@ -1,19 +1,32 @@ import React from "react"; import { Row, Col, Skeleton } from "antd"; import { useQueryParam, StringParam } from "use-query-params"; -import { Repo } from "shared/components"; +import { Repo, User } from "shared/components"; import { SearchType } from "models"; -import { useSearchQuery, RepoFieldsFragment } from "./queries.gen"; +import { useSearchQuery, RepoFieldsFragment, UserFieldsFragment } from "./queries.gen"; import "./index.scss"; +// !!! FIXME: decompose + +const typesMap: { + [key: string]: SearchType; +} = { + repositories: SearchType.Repository, + users: SearchType.User, +}; + /** * @page Search */ const SearchPage = () => { - const type = SearchType.Repository; - const [query] = useQueryParam("q", StringParam); + const [searchQuery] = useQueryParam("q", StringParam); + const [searchType] = useQueryParam("type", StringParam); + const searchTypeEnum = typesMap[searchType || "repositories"]; const { data, loading } = useSearchQuery({ - variables: { type, query: query || "" }, + variables: { + type: searchTypeEnum, + query: searchQuery || "", + }, }); const isEmpty = !loading && (!data || data.search.edges?.length === 0); @@ -22,7 +35,7 @@ const SearchPage = () => {
- Results by {query} search + Results by {searchQuery} search
{loading && ( @@ -32,18 +45,32 @@ const SearchPage = () => { )} - {data?.search.edges?.map((edge) => { - // !!! FIXME: specify types - if (type === SearchType.Repository) { - const data = edge?.node as RepoFieldsFragment; - return ( - - - - ); - } - return "???"; - })} + {/* FIXME: as wrapper? */} + {/* FIXME: Пока что фильтруем Организации, т.к. под них нужна отдельная страница и логика */} + {data?.search.edges + // @ts-ignore FIXME: specify types + ?.filter((edge) => edge?.node?.__typename !== "Organization") + .map((edge) => { + // !!! FIXME: specify types + // FIXME: simplify + if (searchTypeEnum === SearchType.Repository) { + const data = edge?.node as RepoFieldsFragment; + return ( + + + + ); + } + if (searchTypeEnum === SearchType.User) { + const data = edge?.node as UserFieldsFragment; + return ( + + + + ); + } + return null; + })} {isEmpty && "Not found anything"}
diff --git a/src/shared/components/index.ts b/src/shared/components/index.ts index 52191de..e538c8a 100644 --- a/src/shared/components/index.ts +++ b/src/shared/components/index.ts @@ -1 +1,2 @@ export { default as Repo } from "./repo"; +export { default as User } from "./user"; diff --git a/src/shared/components/user/index.scss b/src/shared/components/user/index.scss new file mode 100644 index 0000000..9aceecb --- /dev/null +++ b/src/shared/components/user/index.scss @@ -0,0 +1,4 @@ +.user { + background-color: var(--clr-gray--100); + border-radius: 10px; +} diff --git a/src/shared/components/user/index.tsx b/src/shared/components/user/index.tsx new file mode 100644 index 0000000..b545c51 --- /dev/null +++ b/src/shared/components/user/index.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import { Button } from "antd"; +import "./index.scss"; + +// !!! FIXME: specify types +const User = (props: any) => { + console.log(props); + const { avatarUrl, login, viewerIsFollowing, bio } = props as Partial; + return ( +
+
+ avatar +
+
+ + {login} + + {bio} +
+
+ +
+
+ ); +}; + +export default User; From b587642dadf44f00b4082ad2a7b9fd7b1e63b568 Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 15:14:01 +0300 Subject: [PATCH 09/17] fix(search): toolbar font #13 --- src/pages/search/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx index 4e761a4..12dea47 100644 --- a/src/pages/search/index.tsx +++ b/src/pages/search/index.tsx @@ -34,9 +34,9 @@ const SearchPage = () => { return ( -
- Results by {searchQuery} search -
+

+ Results by {searchQuery} search: +

{loading && ( <> From d57f4e183bf48cde19d039c5b56fb0df687e09aa Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 15:19:29 +0300 Subject: [PATCH 10/17] refactor(search): move tab to shared #13 --- src/features/repo-list/index.tsx | 9 ++++----- src/shared/components/index.ts | 1 + src/shared/components/tabs/index.tsx | 13 +++++++++++++ .../tab => shared/components/tabs/item}/index.scss | 0 .../tab => shared/components/tabs/item}/index.tsx | 0 5 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 src/shared/components/tabs/index.tsx rename src/{features/repo-list/tab => shared/components/tabs/item}/index.scss (100%) rename src/{features/repo-list/tab => shared/components/tabs/item}/index.tsx (100%) diff --git a/src/features/repo-list/index.tsx b/src/features/repo-list/index.tsx index ebb0692..79cc230 100644 --- a/src/features/repo-list/index.tsx +++ b/src/features/repo-list/index.tsx @@ -1,7 +1,6 @@ import React from "react"; -import { Repo } from "shared/components"; +import { Repo, Tabs } from "shared/components"; import { useReposQuery } from "./queries.gen"; -import Tab from "./tab"; import "./index.scss"; type Props = { @@ -17,9 +16,9 @@ const RepoList = ({ username }: Props) => { return (
-
- -
+ + +
{data?.user?.repositories.edges?.map((edge, index) => ( // FIXME: destruct more elegant later diff --git a/src/shared/components/index.ts b/src/shared/components/index.ts index e538c8a..48814d9 100644 --- a/src/shared/components/index.ts +++ b/src/shared/components/index.ts @@ -1,2 +1,3 @@ export { default as Repo } from "./repo"; export { default as User } from "./user"; +export { default as Tabs } from "./tabs"; diff --git a/src/shared/components/tabs/index.tsx b/src/shared/components/tabs/index.tsx new file mode 100644 index 0000000..3d92c95 --- /dev/null +++ b/src/shared/components/tabs/index.tsx @@ -0,0 +1,13 @@ +import React from "react"; +import cn from "classnames"; +import Item from "./item"; + +type Props = PropsWithChildren<{ + className?: string; +}>; +const Tabs = ({ children, className }: Props) => { + return
{children}
; +}; + +Tabs.Item = Item; +export default Tabs; diff --git a/src/features/repo-list/tab/index.scss b/src/shared/components/tabs/item/index.scss similarity index 100% rename from src/features/repo-list/tab/index.scss rename to src/shared/components/tabs/item/index.scss diff --git a/src/features/repo-list/tab/index.tsx b/src/shared/components/tabs/item/index.tsx similarity index 100% rename from src/features/repo-list/tab/index.tsx rename to src/shared/components/tabs/item/index.tsx From 7c76e9d50f83d345af4c3ac20a0ddc364f5782a8 Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 15:22:47 +0300 Subject: [PATCH 11/17] feat(search): specify placeholder #13 --- src/pages/search/index.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx index 12dea47..7a05ffc 100644 --- a/src/pages/search/index.tsx +++ b/src/pages/search/index.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Row, Col, Skeleton } from "antd"; +import { Row, Col, Skeleton, Empty } from "antd"; import { useQueryParam, StringParam } from "use-query-params"; import { Repo, User } from "shared/components"; import { SearchType } from "models"; @@ -17,6 +17,7 @@ const typesMap: { /** * @page Search + * !!! TODO: split by features!!! */ const SearchPage = () => { const [searchQuery] = useQueryParam("q", StringParam); @@ -71,7 +72,7 @@ const SearchPage = () => { } return null; })} - {isEmpty && "Not found anything"} + {isEmpty && }
From 4a79e6086ae7589f4e972270e06503df2a1ad7d1 Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 15:31:24 +0300 Subject: [PATCH 12/17] feat(search): add search-type switching by tabs #13 --- src/pages/search/index.scss | 4 ++++ src/pages/search/index.tsx | 27 ++++++++++++++++------ src/shared/components/tabs/item/index.scss | 9 ++++++-- src/shared/components/tabs/item/index.tsx | 12 ++++++++-- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/pages/search/index.scss b/src/pages/search/index.scss index 4f2ff6d..d013dea 100644 --- a/src/pages/search/index.scss +++ b/src/pages/search/index.scss @@ -13,4 +13,8 @@ box-shadow: 0 5px 0 var(--clr-primary--active); } } + + .filters__item { + text-align: left; + } } diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx index 7a05ffc..a8d327a 100644 --- a/src/pages/search/index.tsx +++ b/src/pages/search/index.tsx @@ -1,7 +1,7 @@ import React from "react"; import { Row, Col, Skeleton, Empty } from "antd"; import { useQueryParam, StringParam } from "use-query-params"; -import { Repo, User } from "shared/components"; +import { Repo, User, Tabs } from "shared/components"; import { SearchType } from "models"; import { useSearchQuery, RepoFieldsFragment, UserFieldsFragment } from "./queries.gen"; import "./index.scss"; @@ -21,7 +21,7 @@ const typesMap: { */ const SearchPage = () => { const [searchQuery] = useQueryParam("q", StringParam); - const [searchType] = useQueryParam("type", StringParam); + const [searchType, setSearchType] = useQueryParam("type", StringParam); const searchTypeEnum = typesMap[searchType || "repositories"]; const { data, loading } = useSearchQuery({ variables: { @@ -75,11 +75,24 @@ const SearchPage = () => { {isEmpty && }
- -
-
Repositories
-
User
-
+ + {/* FIXME: resolve on tabs level */} + + {/* FIXME: resolve on tabs level */} + {/* FIXME: simplify */} + setSearchType("repositories")} + /> + setSearchType("users")} + /> + ); diff --git a/src/shared/components/tabs/item/index.scss b/src/shared/components/tabs/item/index.scss index ffd08f5..a605d05 100644 --- a/src/shared/components/tabs/item/index.scss +++ b/src/shared/components/tabs/item/index.scss @@ -4,12 +4,17 @@ font-size: 19px; line-height: 33px; color: #000000; - background: linear-gradient(270deg, rgba(51, 153, 255, 0) 8.76%, rgba(51, 153, 255, 0.33) 100%); + background: linear-gradient(270deg, rgba(238, 238, 238, 0.24) 35.11%, var(--clr-gray--100) 100%); border: none; border-radius: 5px; - outline-style: none; + outline: none; + transition: var(--transition); &:hover { cursor: pointer; } + + &.active { + background: linear-gradient(270deg, rgba(51, 153, 255, 0) 8.76%, rgba(51, 153, 255, 0.33) 100%); + } } diff --git a/src/shared/components/tabs/item/index.tsx b/src/shared/components/tabs/item/index.tsx index 5be800f..b7b3914 100644 --- a/src/shared/components/tabs/item/index.tsx +++ b/src/shared/components/tabs/item/index.tsx @@ -1,12 +1,20 @@ import React from "react"; +import cn from "classnames"; import "./index.scss"; type Props = { name: string; + className?: string; + active?: boolean; + onClick?: Callback; }; -const Tab = (props: Props) => { - return ; +const Tab = ({ name, className, active, onClick }: Props) => { + return ( + + ); }; export default Tab; From 89126fa7b20e6265799c6a84481c3a57188a615c Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 15:33:13 +0300 Subject: [PATCH 13/17] fix(search): validate search-term #13 --- src/app/header/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/header/index.tsx b/src/app/header/index.tsx index d50725e..8ed8ddb 100644 --- a/src/app/header/index.tsx +++ b/src/app/header/index.tsx @@ -26,7 +26,8 @@ const Header = () => { placeholder="Search..." defaultValue={search} onKeyDown={({ key, target }) => { - if (key === "Enter") { + // @ts-ignore FIXME: specify types + if (key === "Enter" && target.value) { // @ts-ignore FIXME: specify types window.location.replace(`/search?q=${target.value}`); } From 2faf0427ec775982e427d90a407b8ba4c3b6ba3e Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 15:44:25 +0300 Subject: [PATCH 14/17] fix(search): user thumb roundness #13 --- src/shared/components/user/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/shared/components/user/index.tsx b/src/shared/components/user/index.tsx index b545c51..b1d803e 100644 --- a/src/shared/components/user/index.tsx +++ b/src/shared/components/user/index.tsx @@ -4,12 +4,11 @@ import "./index.scss"; // !!! FIXME: specify types const User = (props: any) => { - console.log(props); const { avatarUrl, login, viewerIsFollowing, bio } = props as Partial; return (
- avatar + avatar
From 966edbb516acc581406c7798fa17b0191a86717f Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 15:44:40 +0300 Subject: [PATCH 15/17] fix(search): repo lang view #13 --- src/shared/components/repo/index.tsx | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/shared/components/repo/index.tsx b/src/shared/components/repo/index.tsx index 911253d..cc1a2ec 100644 --- a/src/shared/components/repo/index.tsx +++ b/src/shared/components/repo/index.tsx @@ -1,6 +1,6 @@ import React from "react"; import dayjs from "dayjs"; -import { Repository } from "models"; +import { Repository, Language } from "models"; // FIXME: replace to ant.design icons import FavBtn from "./fav-btn"; import "./index.scss"; @@ -12,7 +12,6 @@ const Repo = (props: Props) => { const { name, primaryLanguage, updatedAt, url, viewerHasStarred, owner } = props as Partial< Repository >; - const hex = primaryLanguage?.color || "#222"; return (
@@ -23,7 +22,8 @@ const Repo = (props: Props) => { {name}
- {primaryLanguage?.name} + + {/* {primaryLanguage?.name} */} Updated on {dayjs(updatedAt).format("D MMM YYYY")}
@@ -32,4 +32,24 @@ const Repo = (props: Props) => { ); }; +// FIXME: specify types +// FIXME: move to shared? (ждем пока появится еще хотя бы 1 место использования) +const Lang = ({ color, name }: Partial) => { + if (!color || !name) return null; + return ( +
+ + {name} +
+ ); +}; + export default Repo; From d636b22579760f618ecae9072470014cf999eb5a Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 15:53:46 +0300 Subject: [PATCH 16/17] refactor(search): minor fix #13 --- src/shared/components/repo/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/components/repo/index.tsx b/src/shared/components/repo/index.tsx index cc1a2ec..a97f379 100644 --- a/src/shared/components/repo/index.tsx +++ b/src/shared/components/repo/index.tsx @@ -8,6 +8,7 @@ import "./index.scss"; // !!! FIXME: specify types type Props = any; +// FIXME: refactor const Repo = (props: Props) => { const { name, primaryLanguage, updatedAt, url, viewerHasStarred, owner } = props as Partial< Repository @@ -23,7 +24,6 @@ const Repo = (props: Props) => {
- {/* {primaryLanguage?.name} */} Updated on {dayjs(updatedAt).format("D MMM YYYY")}
From e2af4cea8a595ed3e9c1beaf17763c7bdb40cecd Mon Sep 17 00:00:00 2001 From: Ilya Azin Date: Wed, 18 Nov 2020 16:38:48 +0300 Subject: [PATCH 17/17] fix(search): sizes && offsets #13 --- src/app/index.scss | 1 + src/app/utils.scss | 5 +++++ src/pages/search/index.tsx | 4 ++-- src/shared/components/repo/index.scss | 9 +++------ src/shared/components/repo/index.tsx | 2 +- src/shared/components/user/index.scss | 3 +++ src/shared/components/user/index.tsx | 6 +++--- 7 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 src/app/utils.scss diff --git a/src/app/index.scss b/src/app/index.scss index 894a898..f6e2283 100644 --- a/src/app/index.scss +++ b/src/app/index.scss @@ -2,6 +2,7 @@ @import "~tailwindcss/dist/utilities.css"; @import "./vars.scss"; @import "./normalize.scss"; +@import "./utils.scss"; .gc-app { display: flex; diff --git a/src/app/utils.scss b/src/app/utils.scss new file mode 100644 index 0000000..0292b1e --- /dev/null +++ b/src/app/utils.scss @@ -0,0 +1,5 @@ +.text-title { + font-family: var(--ff-secondary); + font-size: 20px; + font-weight: var(--fw--medium); +} diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx index a8d327a..5707ff3 100644 --- a/src/pages/search/index.tsx +++ b/src/pages/search/index.tsx @@ -34,7 +34,7 @@ const SearchPage = () => { return ( - +

Results by {searchQuery} search:

@@ -75,7 +75,7 @@ const SearchPage = () => { {isEmpty && }
- + {/* FIXME: resolve on tabs level */} {/* FIXME: resolve on tabs level */} diff --git a/src/shared/components/repo/index.scss b/src/shared/components/repo/index.scss index 6c72739..f6e6b6e 100644 --- a/src/shared/components/repo/index.scss +++ b/src/shared/components/repo/index.scss @@ -5,6 +5,9 @@ height: 140px; padding: 22px; margin-top: 22px; + // FIXME: define on app level + font-family: var(--ff-secondary); + font-size: 14px; background-color: var(--clr-gray--100); border-radius: 10px; @@ -13,16 +16,10 @@ align-content: space-between; a { - font-family: var(--ff-secondary); - font-size: 20px; - font-weight: var(--fw--medium); color: var(--clr-text); } span { - font-family: var(--ff-secondary); - font-size: 14px; - font-weight: var(--fw--regular); line-height: 24px; } } diff --git a/src/shared/components/repo/index.tsx b/src/shared/components/repo/index.tsx index a97f379..74be7e2 100644 --- a/src/shared/components/repo/index.tsx +++ b/src/shared/components/repo/index.tsx @@ -18,7 +18,7 @@ const Repo = (props: Props) => {
{/* FIXME: hardcoded, replace to generation by {username}/{reponame} */} - + {owner?.login && `${owner.login}/`} {name} diff --git a/src/shared/components/user/index.scss b/src/shared/components/user/index.scss index 9aceecb..6c99a69 100644 --- a/src/shared/components/user/index.scss +++ b/src/shared/components/user/index.scss @@ -1,4 +1,7 @@ .user { + // FIXME: define on app level + font-family: var(--ff-secondary); + font-size: 14px; background-color: var(--clr-gray--100); border-radius: 10px; } diff --git a/src/shared/components/user/index.tsx b/src/shared/components/user/index.tsx index b1d803e..b5e4321 100644 --- a/src/shared/components/user/index.tsx +++ b/src/shared/components/user/index.tsx @@ -10,13 +10,13 @@ const User = (props: any) => {
avatar
-
- + -
+