feat: base profile about card, update profile api, add extra fields to users table

This commit is contained in:
MTG2000
2022-06-04 14:15:04 +03:00
parent 526084771c
commit 846924eaeb
22 changed files with 590 additions and 46 deletions

View File

@@ -36,6 +36,19 @@ export interface NexusGenInputs {
title: string; // String!
topicId: number; // Int!
}
UpdateProfileInput: { // input type
avatar?: string | null; // String
bio?: string | null; // String
email?: string | null; // String
github?: string | null; // String
jobTitle?: string | null; // String
lightning_address?: string | null; // String
linkedin?: string | null; // String
location?: string | null; // String
name?: string | null; // String
twitter?: string | null; // String
website?: string | null; // String
}
}
export interface NexusGenEnums {
@@ -53,6 +66,12 @@ export interface NexusGenScalars {
}
export interface NexusGenObjects {
Author: { // root type
avatar: string; // String!
id: number; // Int!
join_date: NexusGenScalars['Date']; // Date!
name: string; // String!
}
Award: { // root type
id: number; // Int!
image: string; // String!
@@ -73,7 +92,7 @@ export interface NexusGenObjects {
votes_count: number; // Int!
}
BountyApplication: { // root type
author: NexusGenRootTypes['User']; // User!
author: NexusGenRootTypes['Author']; // Author!
date: string; // String!
id: number; // Int!
workplan: string; // String!
@@ -116,7 +135,7 @@ export interface NexusGenObjects {
}
Mutation: {};
PostComment: { // root type
author: NexusGenRootTypes['User']; // User!
author: NexusGenRootTypes['Author']; // Author!
body: string; // String!
createdAt: NexusGenScalars['Date']; // Date!
id: number; // Int!
@@ -165,9 +184,19 @@ export interface NexusGenObjects {
}
User: { // root type
avatar: string; // String!
bio?: string | null; // String
email?: string | null; // String
github?: string | null; // String
id: number; // Int!
jobTitle?: string | null; // String
join_date: NexusGenScalars['Date']; // Date!
lightning_address?: string | null; // String
linkedin?: string | null; // String
location?: string | null; // String
name: string; // String!
role?: string | null; // String
twitter?: string | null; // String
website?: string | null; // String
}
Vote: { // root type
amount_in_sat: number; // Int!
@@ -193,6 +222,12 @@ export type NexusGenRootTypes = NexusGenInterfaces & NexusGenObjects & NexusGenU
export type NexusGenAllTypes = NexusGenRootTypes & NexusGenScalars & NexusGenEnums
export interface NexusGenFieldTypes {
Author: { // field return type
avatar: string; // String!
id: number; // Int!
join_date: NexusGenScalars['Date']; // Date!
name: string; // String!
}
Award: { // field return type
id: number; // Int!
image: string; // String!
@@ -203,7 +238,7 @@ export interface NexusGenFieldTypes {
Bounty: { // field return type
applicants_count: number; // Int!
applications: NexusGenRootTypes['BountyApplication'][]; // [BountyApplication!]!
author: NexusGenRootTypes['User']; // User!
author: NexusGenRootTypes['Author']; // Author!
body: string; // String!
cover_image: string; // String!
createdAt: NexusGenScalars['Date']; // Date!
@@ -217,7 +252,7 @@ export interface NexusGenFieldTypes {
votes_count: number; // Int!
}
BountyApplication: { // field return type
author: NexusGenRootTypes['User']; // User!
author: NexusGenRootTypes['Author']; // Author!
date: string; // String!
id: number; // Int!
workplan: string; // String!
@@ -268,10 +303,11 @@ export interface NexusGenFieldTypes {
confirmVote: NexusGenRootTypes['Vote']; // Vote!
createStory: NexusGenRootTypes['Story'] | null; // Story
donate: NexusGenRootTypes['Donation']; // Donation!
updateProfile: NexusGenRootTypes['User'] | null; // User
vote: NexusGenRootTypes['Vote']; // Vote!
}
PostComment: { // field return type
author: NexusGenRootTypes['User']; // User!
author: NexusGenRootTypes['Author']; // Author!
body: string; // String!
createdAt: NexusGenScalars['Date']; // Date!
id: number; // Int!
@@ -309,12 +345,13 @@ export interface NexusGenFieldTypes {
me: NexusGenRootTypes['User'] | null; // User
newProjects: NexusGenRootTypes['Project'][]; // [Project!]!
popularTopics: NexusGenRootTypes['Topic'][]; // [Topic!]!
profile: NexusGenRootTypes['User'] | null; // User
projectsByCategory: NexusGenRootTypes['Project'][]; // [Project!]!
searchProjects: NexusGenRootTypes['Project'][]; // [Project!]!
}
Question: { // field return type
answers_count: number; // Int!
author: NexusGenRootTypes['User']; // User!
author: NexusGenRootTypes['Author']; // Author!
body: string; // String!
comments: NexusGenRootTypes['PostComment'][]; // [PostComment!]!
createdAt: NexusGenScalars['Date']; // Date!
@@ -326,7 +363,7 @@ export interface NexusGenFieldTypes {
votes_count: number; // Int!
}
Story: { // field return type
author: NexusGenRootTypes['User']; // User!
author: NexusGenRootTypes['Author']; // Author!
body: string; // String!
comments: NexusGenRootTypes['PostComment'][]; // [PostComment!]!
comments_count: number; // Int!
@@ -351,9 +388,19 @@ export interface NexusGenFieldTypes {
}
User: { // field return type
avatar: string; // String!
bio: string | null; // String
email: string | null; // String
github: string | null; // String
id: number; // Int!
jobTitle: string | null; // String
join_date: NexusGenScalars['Date']; // Date!
lightning_address: string | null; // String
linkedin: string | null; // String
location: string | null; // String
name: string; // String!
role: string | null; // String
twitter: string | null; // String
website: string | null; // String
}
Vote: { // field return type
amount_in_sat: number; // Int!
@@ -375,6 +422,12 @@ export interface NexusGenFieldTypes {
}
export interface NexusGenFieldTypeNames {
Author: { // field return type name
avatar: 'String'
id: 'Int'
join_date: 'Date'
name: 'String'
}
Award: { // field return type name
id: 'Int'
image: 'String'
@@ -385,7 +438,7 @@ export interface NexusGenFieldTypeNames {
Bounty: { // field return type name
applicants_count: 'Int'
applications: 'BountyApplication'
author: 'User'
author: 'Author'
body: 'String'
cover_image: 'String'
createdAt: 'Date'
@@ -399,7 +452,7 @@ export interface NexusGenFieldTypeNames {
votes_count: 'Int'
}
BountyApplication: { // field return type name
author: 'User'
author: 'Author'
date: 'String'
id: 'Int'
workplan: 'String'
@@ -450,10 +503,11 @@ export interface NexusGenFieldTypeNames {
confirmVote: 'Vote'
createStory: 'Story'
donate: 'Donation'
updateProfile: 'User'
vote: 'Vote'
}
PostComment: { // field return type name
author: 'User'
author: 'Author'
body: 'String'
createdAt: 'Date'
id: 'Int'
@@ -491,12 +545,13 @@ export interface NexusGenFieldTypeNames {
me: 'User'
newProjects: 'Project'
popularTopics: 'Topic'
profile: 'User'
projectsByCategory: 'Project'
searchProjects: 'Project'
}
Question: { // field return type name
answers_count: 'Int'
author: 'User'
author: 'Author'
body: 'String'
comments: 'PostComment'
createdAt: 'Date'
@@ -508,7 +563,7 @@ export interface NexusGenFieldTypeNames {
votes_count: 'Int'
}
Story: { // field return type name
author: 'User'
author: 'Author'
body: 'String'
comments: 'PostComment'
comments_count: 'Int'
@@ -533,9 +588,19 @@ export interface NexusGenFieldTypeNames {
}
User: { // field return type name
avatar: 'String'
bio: 'String'
email: 'String'
github: 'String'
id: 'Int'
jobTitle: 'String'
join_date: 'Date'
lightning_address: 'String'
linkedin: 'String'
location: 'String'
name: 'String'
role: 'String'
twitter: 'String'
website: 'String'
}
Vote: { // field return type name
amount_in_sat: 'Int'
@@ -572,6 +637,9 @@ export interface NexusGenArgTypes {
donate: { // args
amount_in_sat: number; // Int!
}
updateProfile: { // args
data?: NexusGenInputs['UpdateProfileInput'] | null; // UpdateProfileInput
}
vote: { // args
amount_in_sat: number; // Int!
item_id: number; // Int!
@@ -614,6 +682,9 @@ export interface NexusGenArgTypes {
skip?: number | null; // Int
take: number | null; // Int
}
profile: { // args
id: number; // Int!
}
projectsByCategory: { // args
category_id: number; // Int!
skip?: number | null; // Int

View File

@@ -2,6 +2,13 @@
### Do not make changes to this file directly
type Author {
avatar: String!
id: Int!
join_date: Date!
name: String!
}
type Award {
id: Int!
image: String!
@@ -13,7 +20,7 @@ type Award {
type Bounty implements PostBase {
applicants_count: Int!
applications: [BountyApplication!]!
author: User!
author: Author!
body: String!
cover_image: String!
createdAt: Date!
@@ -28,7 +35,7 @@ type Bounty implements PostBase {
}
type BountyApplication {
author: User!
author: Author!
date: String!
id: Int!
workplan: String!
@@ -88,6 +95,7 @@ type Mutation {
confirmVote(payment_request: String!, preimage: String!): Vote!
createStory(data: StoryInputType): Story
donate(amount_in_sat: Int!): Donation!
updateProfile(data: UpdateProfileInput): User
vote(amount_in_sat: Int!, item_id: Int!, item_type: VOTE_ITEM_TYPE!): Vote!
}
@@ -109,7 +117,7 @@ interface PostBase {
}
type PostComment {
author: User!
author: Author!
body: String!
createdAt: Date!
id: Int!
@@ -149,13 +157,14 @@ type Query {
me: User
newProjects(skip: Int = 0, take: Int = 50): [Project!]!
popularTopics: [Topic!]!
profile(id: Int!): User
projectsByCategory(category_id: Int!, skip: Int = 0, take: Int = 10): [Project!]!
searchProjects(search: String!, skip: Int = 0, take: Int = 50): [Project!]!
}
type Question implements PostBase {
answers_count: Int!
author: User!
author: Author!
body: String!
comments: [PostComment!]!
createdAt: Date!
@@ -168,7 +177,7 @@ type Question implements PostBase {
}
type Story implements PostBase {
author: User!
author: Author!
body: String!
comments: [PostComment!]!
comments_count: Int!
@@ -203,11 +212,35 @@ type Topic {
title: String!
}
input UpdateProfileInput {
avatar: String
bio: String
email: String
github: String
jobTitle: String
lightning_address: String
linkedin: String
location: String
name: String
twitter: String
website: String
}
type User {
avatar: String!
bio: String
email: String
github: String
id: Int!
jobTitle: String
join_date: Date!
lightning_address: String
linkedin: String
location: String
name: String!
role: String
twitter: String
website: String
}
enum VOTE_ITEM_TYPE {

View File

@@ -67,10 +67,21 @@ const paginationArgs = (args) => {
}
}
const removeNulls = (obj) => {
let res = {};
for (const key in obj) {
if (obj[key] != null) {
res[key] = obj[key];
}
}
return res
}
module.exports = {
getPaymetRequestForItem,
hexToUint8Array,
lightningAddressToLnurl,
getLnurlDetails,
paginationArgs
paginationArgs,
removeNulls
}

View File

@@ -39,6 +39,16 @@ const Topic = objectType({
}
})
const Author = objectType({
name: 'Author',
definition(t) {
t.nonNull.int('id');
t.nonNull.string('name');
t.nonNull.string('avatar');
t.nonNull.date('join_date');
}
})
const allTopics = extendType({
type: "Query",
@@ -129,7 +139,7 @@ const Story = objectType({
}
})
t.nonNull.field('author', {
type: "User",
type: "Author",
resolve: (parent) =>
prisma.story.findUnique({ where: { id: parent.id } }).user()
@@ -214,7 +224,7 @@ const BountyApplication = objectType({
t.nonNull.string('date');
t.nonNull.string('workplan');
t.nonNull.field('author', {
type: "User"
type: "Author"
});
}
})
@@ -234,7 +244,7 @@ const Bounty = objectType({
type: "BountyApplication"
});
t.nonNull.field('author', {
type: "User",
type: "Author",
resolve: (parent) => {
return prisma.bounty.findUnique({ where: { id: parent.id } }).user();
}
@@ -270,7 +280,7 @@ const Question = objectType({
});
t.nonNull.field('author', {
type: "User",
type: "Author",
resolve: (parent) => {
return prisma.question.findUnique({ where: { id: parent.id } }).user();
}
@@ -285,7 +295,7 @@ const PostComment = objectType({
t.nonNull.date('createdAt');
t.nonNull.string('body');
t.nonNull.field('author', {
type: "User"
type: "Author"
});
t.int('parentId');
t.nonNull.int('votes_count');
@@ -391,6 +401,7 @@ const getPostById = extendType({
module.exports = {
// Types
POST_TYPE,
Author,
Topic,
PostBase,
BountyApplication,

View File

@@ -1,5 +1,7 @@
const { objectType, extendType } = require("nexus");
const { prisma } = require("../../prisma");
const { objectType, extendType, intArg, nonNull, inputObjectType } = require("nexus");
const { getUserByPubKey } = require("../../auth/utils/helperFuncs");
const { removeNulls } = require("./helpers");
@@ -10,6 +12,16 @@ const User = objectType({
t.nonNull.string('name');
t.nonNull.string('avatar');
t.nonNull.date('join_date');
t.string('role');
t.string('email')
t.string('jobTitle')
t.string('lightning_address')
t.string('website')
t.string('twitter')
t.string('github')
t.string('linkedin')
t.string('bio')
t.string('location')
}
})
@@ -27,10 +39,77 @@ const me = extendType({
}
})
const profile = extendType({
type: "Query",
definition(t) {
t.field('profile', {
type: "User",
args: {
id: nonNull(intArg())
},
async resolve(parent, { id }) {
return prisma.user.findFirst({
where: { id }
})
}
})
}
})
const UpdateProfileInput = inputObjectType({
name: 'UpdateProfileInput',
definition(t) {
t.string('name');
t.string('avatar');
t.string('email')
t.string('jobTitle')
t.string('lightning_address')
t.string('website')
t.string('twitter')
t.string('github')
t.string('linkedin')
t.string('bio')
t.string('location')
}
})
const updateProfile = extendType({
type: 'Mutation',
definition(t) {
t.field('updateProfile', {
type: 'User',
args: { data: UpdateProfileInput },
async resolve(_root, args, ctx) {
const user = await getUserByPubKey(ctx.userPubKey);
// Do some validation
if (!user)
throw new Error("You have to login");
// TODO: validate new data
// Preprocess & insert
return prisma.user.update({
where: {
id: user.id,
},
data: removeNulls(args.data)
})
}
})
},
})
module.exports = {
// Types
User,
UpdateProfileInput,
// Queries
me,
profile,
// Mutations
updateProfile,
}

View File

@@ -0,0 +1,6 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "bio" TEXT,
ADD COLUMN "github" TEXT,
ADD COLUMN "location" TEXT,
ADD COLUMN "role" TEXT NOT NULL DEFAULT E'user',
ADD COLUMN "twitter" TEXT;

View File

@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "jobTitle" TEXT,
ADD COLUMN "linkedin" TEXT;

View File

@@ -38,13 +38,23 @@ model Vote {
model User {
id Int @id @default(autoincrement())
pubKey String? @unique
name String? @unique
avatar String?
role String @default("user")
name String? @unique
email String?
website String?
jobTitle String?
lightning_address String?
avatar String?
join_date DateTime @default(now())
website String?
twitter String?
github String?
linkedin String?
bio String?
location String?
join_date DateTime @default(now())
stories Story[]
questions Question[]

View File

@@ -25,6 +25,7 @@ const HackathonsPage = React.lazy(() => import("./features/Hackathons/pages/Hack
const DonatePage = React.lazy(() => import("./features/Donations/pages/DonatePage/DonatePage"))
const LoginPage = React.lazy(() => import("./features/Auth/pages/LoginPage/LoginPage"))
const LogoutPage = React.lazy(() => import("./features/Auth/pages/LogoutPage/LogoutPage"))
const ProfilePage = React.lazy(() => import("./features/Profiles/pages/ProfilePage/ProfilePage"))
function App() {
const { isWalletConnected } = useAppSelector(state => ({
@@ -77,6 +78,7 @@ function App() {
<Route path="/donate" element={<DonatePage />} />
<Route path="/profile/:id" element={<ProfilePage />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/logout" element={<LogoutPage />} />

View File

@@ -69,6 +69,13 @@ export default function InsertImageModal({ onClose, direction, callbackAction, .
</div>
</div>
</div>
<div className="mt-32 w-1/2 mx-auto aspect-video bg-gray-200 rounded-10">
{urlInput && <img
src={urlInput}
className='w-full h-full object-cover rounded-10'
alt={altInput}
/>}
</div>
<div className="flex gap-16 justify-end mt-32">
<Button onClick={onClose}>
Cancel

View File

@@ -169,9 +169,14 @@ export default function NavDesktop() {
(curUser ?
<Menu menuButton={<MenuButton ><Avatar src={curUser.avatar} width={40} /> </MenuButton>}>
<MenuItem
className='!p-16 font-medium flex gap-16 hover:bg-gray-100 !rounded-12 opacity-60'
href={`/profile/${curUser.id}`}
onClick={(e) => {
e.syntheticEvent.preventDefault();
navigate(`/profile/${curUser.id}`);
}}
className='!p-16 font-medium flex gap-16 hover:bg-gray-100 !rounded-12'
>
Profile (soon)
Profile
</MenuItem>
<MenuItem
href="/logout"

View File

@@ -3,5 +3,6 @@ query Me {
id
name
avatar
join_date
}
}

View File

@@ -73,9 +73,9 @@ export default function StoryForm() {
cover_image: story?.cover_image ?? [],
tags: story?.tags ?? [],
body: story?.body ?? '',
}
},
});
const { handleSubmit, control, register, formState: { errors, }, trigger, getValues } = formMethods;
const { handleSubmit, control, register, formState: { errors, }, trigger, getValues, } = formMethods;
const [loading, setLoading] = useState(false)
const navigate = useNavigate()

View File

@@ -8,6 +8,7 @@ query Feed($take: Int, $skip: Int, $sortBy: String, $topic: Int) {
id
name
avatar
join_date
}
excerpt
tags {
@@ -27,6 +28,7 @@ query Feed($take: Int, $skip: Int, $sortBy: String, $topic: Int) {
id
name
avatar
join_date
}
excerpt
tags {
@@ -48,6 +50,7 @@ query Feed($take: Int, $skip: Int, $sortBy: String, $topic: Int) {
id
name
avatar
join_date
}
excerpt
tags {
@@ -65,6 +68,7 @@ query Feed($take: Int, $skip: Int, $sortBy: String, $topic: Int) {
id
name
avatar
join_date
}
}
}

View File

@@ -7,9 +7,7 @@ export type User = {
avatar: string
}
export type Author = User & {
join_date?: string
}
export type Author = ApiTypes.Author
export type PostBase1 = {
id: number

View File

@@ -7,7 +7,7 @@ interface Props {
export default function Avatar({ src, alt, width = 40 }: Props) {
return (
<img src={src} className='shrink-0 rounded-full object-contain border-2 border-gray-100' style={{
<img src={src} className='shrink-0 rounded-full object-contain border-2 bg-white border-gray-100' style={{
width: width,
height: width,
}} alt={alt ?? "avatar"} />

View File

@@ -0,0 +1,74 @@
import Avatar from "src/features/Profiles/Components/Avatar/Avatar"
import { User } from "src/graphql"
import { trimText } from "src/utils/helperFunctions"
import { FiGithub, FiGlobe, FiLinkedin, FiTwitter } from 'react-icons/fi'
interface Props {
user: Pick<User,
| 'name'
| 'email'
| 'jobTitle'
| 'avatar'
| 'website'
| 'github'
| 'twitter'
| 'linkedin'
| 'location'
| 'bio'
>
}
export default function AboutCard({ user }: Props) {
return (
<div className="rounded-16 bg-white border-2 border-gray-200">
<div className="bg-gray-600 relative h-[160px] rounded-t-16">
<div className="absolute left-24 bottom-0 translate-y-1/2">
<Avatar src={user.avatar} width={120} />
</div>
</div>
<div className="h-64"></div>
<div className="p-24 pt-0 flex flex-col gap-16">
<h1 className="text-h2 font-bolder">
{trimText(user.name, 20)}
</h1>
<div className="flex flex-wrap gap-16">
{user.website && <a
href={user.website}
className="text-body4 text-primary-700 font-medium"
target='_blank'
rel="noreferrer">
<FiGlobe className="scale-125 mr-8" /> <span className="align-middle">Website</span>
</a>}
{user.twitter && <a
href={`https://twitter.com/@${user.twitter}`}
className="text-body4 text-primary-700 font-medium"
target='_blank'
rel="noreferrer">
<FiTwitter className="scale-125 mr-8" /> <span className="align-middle">{user.twitter}</span>
</a>}
{user.github && <a
href={`https://github.com/${user.github}`}
className="text-body4 text-primary-700 font-medium"
target='_blank'
rel="noreferrer">
<FiGithub className="scale-125 mr-8" /> <span className="align-middle">{user.github}</span>
</a>}
{user.linkedin && <a
href={user.linkedin}
className="text-body4 text-primary-700 font-medium"
target='_blank'
rel="noreferrer">
<FiLinkedin className="scale-125 mr-8" /> <span className="align-middle">LinkedIn</span>
</a>}
</div>
{user.jobTitle && <p className="text-body4 font-medium">
{user.jobTitle}
</p>}
{user.bio && <p className="text-body5 font-medium">
{user.bio}
</p>}
</div>
</div>
)
}

View File

@@ -0,0 +1,37 @@
import { useParams } from "react-router-dom"
import LoadingPage from "src/Components/LoadingPage/LoadingPage"
import NotFoundPage from "src/features/Shared/pages/NotFoundPage/NotFoundPage"
import { useProfileQuery } from "src/graphql"
import AboutCard from "./AboutCard/AboutCard"
export default function ProfilePage() {
const { id } = useParams()
const profileQuery = useProfileQuery({
variables: {
profileId: Number(id!),
},
skip: isNaN(Number(id)),
})
if (profileQuery.loading)
return <LoadingPage />
if (!profileQuery.data?.profile)
return <NotFoundPage />
return (
<div className="grid gap-24"
style={{ gridTemplateColumns: "1fr 2fr 1fr" }}
>
<aside></aside>
<main>
<AboutCard user={profileQuery.data.profile} />
</main>
<aside></aside>
</div>
)
}

View File

@@ -0,0 +1,18 @@
query profile($profileId: Int!) {
profile(id: $profileId) {
id
name
avatar
join_date
role
email
jobTitle
lightning_address
website
twitter
github
linkedin
bio
location
}
}

View File

@@ -0,0 +1,16 @@
mutation updateProfileAbout($data: UpdateProfileInput) {
updateProfile(data: $data) {
id
name
avatar
join_date
role
email
lightning_address
website
twitter
github
bio
location
}
}

View File

@@ -17,6 +17,14 @@ export type Scalars = {
Date: any;
};
export type Author = {
__typename?: 'Author';
avatar: Scalars['String'];
id: Scalars['Int'];
join_date: Scalars['Date'];
name: Scalars['String'];
};
export type Award = {
__typename?: 'Award';
id: Scalars['Int'];
@@ -30,7 +38,7 @@ export type Bounty = PostBase & {
__typename?: 'Bounty';
applicants_count: Scalars['Int'];
applications: Array<BountyApplication>;
author: User;
author: Author;
body: Scalars['String'];
cover_image: Scalars['String'];
createdAt: Scalars['Date'];
@@ -46,7 +54,7 @@ export type Bounty = PostBase & {
export type BountyApplication = {
__typename?: 'BountyApplication';
author: User;
author: Author;
date: Scalars['String'];
id: Scalars['Int'];
workplan: Scalars['String'];
@@ -109,6 +117,7 @@ export type Mutation = {
confirmVote: Vote;
createStory: Maybe<Story>;
donate: Donation;
updateProfile: Maybe<User>;
vote: Vote;
};
@@ -135,6 +144,11 @@ export type MutationDonateArgs = {
};
export type MutationUpdateProfileArgs = {
data: InputMaybe<UpdateProfileInput>;
};
export type MutationVoteArgs = {
amount_in_sat: Scalars['Int'];
item_id: Scalars['Int'];
@@ -160,7 +174,7 @@ export type PostBase = {
export type PostComment = {
__typename?: 'PostComment';
author: User;
author: Author;
body: Scalars['String'];
createdAt: Scalars['Date'];
id: Scalars['Int'];
@@ -202,6 +216,7 @@ export type Query = {
me: Maybe<User>;
newProjects: Array<Project>;
popularTopics: Array<Topic>;
profile: Maybe<User>;
projectsByCategory: Array<Project>;
searchProjects: Array<Project>;
};
@@ -260,6 +275,11 @@ export type QueryNewProjectsArgs = {
};
export type QueryProfileArgs = {
id: Scalars['Int'];
};
export type QueryProjectsByCategoryArgs = {
category_id: Scalars['Int'];
skip?: InputMaybe<Scalars['Int']>;
@@ -276,7 +296,7 @@ export type QuerySearchProjectsArgs = {
export type Question = PostBase & {
__typename?: 'Question';
answers_count: Scalars['Int'];
author: User;
author: Author;
body: Scalars['String'];
comments: Array<PostComment>;
createdAt: Scalars['Date'];
@@ -290,7 +310,7 @@ export type Question = PostBase & {
export type Story = PostBase & {
__typename?: 'Story';
author: User;
author: Author;
body: Scalars['String'];
comments: Array<PostComment>;
comments_count: Scalars['Int'];
@@ -327,11 +347,34 @@ export type Topic = {
title: Scalars['String'];
};
export type UpdateProfileInput = {
avatar: InputMaybe<Scalars['String']>;
bio: InputMaybe<Scalars['String']>;
email: InputMaybe<Scalars['String']>;
github: InputMaybe<Scalars['String']>;
lightning_address: InputMaybe<Scalars['String']>;
location: InputMaybe<Scalars['String']>;
name: InputMaybe<Scalars['String']>;
twitter: InputMaybe<Scalars['String']>;
website: InputMaybe<Scalars['String']>;
};
export type User = {
__typename?: 'User';
avatar: Scalars['String'];
bio: Maybe<Scalars['String']>;
email: Maybe<Scalars['String']>;
github: Maybe<Scalars['String']>;
id: Scalars['Int'];
jobTitle: Maybe<Scalars['String']>;
join_date: Scalars['Date'];
lightning_address: Maybe<Scalars['String']>;
linkedin: Maybe<Scalars['String']>;
location: Maybe<Scalars['String']>;
name: Scalars['String'];
role: Maybe<Scalars['String']>;
twitter: Maybe<Scalars['String']>;
website: Maybe<Scalars['String']>;
};
export enum Vote_Item_Type {
@@ -369,7 +412,7 @@ export type SearchProjectsQuery = { __typename?: 'Query', searchProjects: Array<
export type MeQueryVariables = Exact<{ [key: string]: never; }>;
export type MeQuery = { __typename?: 'Query', me: { __typename?: 'User', id: number, name: string, avatar: string } | null };
export type MeQuery = { __typename?: 'Query', me: { __typename?: 'User', id: number, name: string, avatar: string, join_date: any } | null };
export type DonationsStatsQueryVariables = Exact<{ [key: string]: never; }>;
@@ -407,7 +450,7 @@ export type GetHackathonsQuery = { __typename?: 'Query', getAllHackathons: Array
export type TrendingPostsQueryVariables = Exact<{ [key: string]: never; }>;
export type TrendingPostsQuery = { __typename?: 'Query', getTrendingPosts: Array<{ __typename?: 'Bounty', id: number, title: string, author: { __typename?: 'User', id: number, avatar: string } } | { __typename?: 'Question', id: number, title: string, author: { __typename?: 'User', id: number, avatar: string } } | { __typename?: 'Story', id: number, title: string, author: { __typename?: 'User', id: number, avatar: string } }> };
export type TrendingPostsQuery = { __typename?: 'Query', getTrendingPosts: Array<{ __typename?: 'Bounty', id: number, title: string, author: { __typename?: 'Author', id: number, avatar: string } } | { __typename?: 'Question', id: number, title: string, author: { __typename?: 'Author', id: number, avatar: string } } | { __typename?: 'Story', id: number, title: string, author: { __typename?: 'Author', id: number, avatar: string } }> };
export type CreateStoryMutationVariables = Exact<{
data: InputMaybe<StoryInputType>;
@@ -429,7 +472,7 @@ export type FeedQueryVariables = Exact<{
}>;
export type FeedQuery = { __typename?: 'Query', getFeed: Array<{ __typename?: 'Bounty', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> }> };
export type FeedQuery = { __typename?: 'Query', getFeed: Array<{ __typename?: 'Bounty', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any } }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> }> };
export type PostDetailsQueryVariables = Exact<{
id: Scalars['Int'];
@@ -437,7 +480,21 @@ export type PostDetailsQueryVariables = Exact<{
}>;
export type PostDetailsQuery = { __typename?: 'Query', getPostById: { __typename?: 'Bounty', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, applications: Array<{ __typename?: 'BountyApplication', id: number, date: string, workplan: string, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } };
export type PostDetailsQuery = { __typename?: 'Query', getPostById: { __typename?: 'Bounty', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, applications: Array<{ __typename?: 'BountyApplication', id: number, date: string, workplan: string, author: { __typename?: 'Author', id: number, name: string, avatar: string } }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'Author', id: number, name: string, avatar: string } }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'Author', id: number, name: string, avatar: string } }> } };
export type ProfileQueryVariables = Exact<{
profileId: Scalars['Int'];
}>;
export type ProfileQuery = { __typename?: 'Query', profile: { __typename?: 'User', id: number, name: string, avatar: string, join_date: any, role: string | null, email: string | null, jobTitle: string | null, lightning_address: string | null, website: string | null, twitter: string | null, github: string | null, linkedin: string | null, bio: string | null, location: string | null } | null };
export type UpdateProfileAboutMutationVariables = Exact<{
data: InputMaybe<UpdateProfileInput>;
}>;
export type UpdateProfileAboutMutation = { __typename?: 'Mutation', updateProfile: { __typename?: 'User', id: number, name: string, avatar: string, join_date: any, role: string | null, email: string | null, lightning_address: string | null, website: string | null, twitter: string | null, github: string | null, bio: string | null, location: string | null } | null };
export type CategoryPageQueryVariables = Exact<{
categoryId: Scalars['Int'];
@@ -570,6 +627,7 @@ export const MeDocument = gql`
id
name
avatar
join_date
}
}
`;
@@ -930,6 +988,7 @@ export const FeedDocument = gql`
id
name
avatar
join_date
}
excerpt
tags {
@@ -949,6 +1008,7 @@ export const FeedDocument = gql`
id
name
avatar
join_date
}
excerpt
tags {
@@ -970,6 +1030,7 @@ export const FeedDocument = gql`
id
name
avatar
join_date
}
excerpt
tags {
@@ -987,6 +1048,7 @@ export const FeedDocument = gql`
id
name
avatar
join_date
}
}
}
@@ -1035,6 +1097,7 @@ export const PostDetailsDocument = gql`
id
name
avatar
join_date
}
body
tags {
@@ -1066,6 +1129,7 @@ export const PostDetailsDocument = gql`
id
name
avatar
join_date
}
body
tags {
@@ -1097,6 +1161,7 @@ export const PostDetailsDocument = gql`
id
name
avatar
join_date
}
body
tags {
@@ -1151,6 +1216,98 @@ export function usePostDetailsLazyQuery(baseOptions?: Apollo.LazyQueryHookOption
export type PostDetailsQueryHookResult = ReturnType<typeof usePostDetailsQuery>;
export type PostDetailsLazyQueryHookResult = ReturnType<typeof usePostDetailsLazyQuery>;
export type PostDetailsQueryResult = Apollo.QueryResult<PostDetailsQuery, PostDetailsQueryVariables>;
export const ProfileDocument = gql`
query profile($profileId: Int!) {
profile(id: $profileId) {
id
name
avatar
join_date
role
email
jobTitle
lightning_address
website
twitter
github
linkedin
bio
location
}
}
`;
/**
* __useProfileQuery__
*
* To run a query within a React component, call `useProfileQuery` and pass it any options that fit your needs.
* When your component renders, `useProfileQuery` 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 } = useProfileQuery({
* variables: {
* profileId: // value for 'profileId'
* },
* });
*/
export function useProfileQuery(baseOptions: Apollo.QueryHookOptions<ProfileQuery, ProfileQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ProfileQuery, ProfileQueryVariables>(ProfileDocument, options);
}
export function useProfileLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ProfileQuery, ProfileQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ProfileQuery, ProfileQueryVariables>(ProfileDocument, options);
}
export type ProfileQueryHookResult = ReturnType<typeof useProfileQuery>;
export type ProfileLazyQueryHookResult = ReturnType<typeof useProfileLazyQuery>;
export type ProfileQueryResult = Apollo.QueryResult<ProfileQuery, ProfileQueryVariables>;
export const UpdateProfileAboutDocument = gql`
mutation updateProfileAbout($data: UpdateProfileInput) {
updateProfile(data: $data) {
id
name
avatar
join_date
role
email
lightning_address
website
twitter
github
bio
location
}
}
`;
export type UpdateProfileAboutMutationFn = Apollo.MutationFunction<UpdateProfileAboutMutation, UpdateProfileAboutMutationVariables>;
/**
* __useUpdateProfileAboutMutation__
*
* To run a mutation, you first call `useUpdateProfileAboutMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useUpdateProfileAboutMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [updateProfileAboutMutation, { data, loading, error }] = useUpdateProfileAboutMutation({
* variables: {
* data: // value for 'data'
* },
* });
*/
export function useUpdateProfileAboutMutation(baseOptions?: Apollo.MutationHookOptions<UpdateProfileAboutMutation, UpdateProfileAboutMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<UpdateProfileAboutMutation, UpdateProfileAboutMutationVariables>(UpdateProfileAboutDocument, options);
}
export type UpdateProfileAboutMutationHookResult = ReturnType<typeof useUpdateProfileAboutMutation>;
export type UpdateProfileAboutMutationResult = Apollo.MutationResult<UpdateProfileAboutMutation>;
export type UpdateProfileAboutMutationOptions = Apollo.BaseMutationOptions<UpdateProfileAboutMutation, UpdateProfileAboutMutationVariables>;
export const CategoryPageDocument = gql`
query CategoryPage($categoryId: Int!) {
projectsByCategory(category_id: $categoryId) {

View File

@@ -5,6 +5,7 @@ interface StoreState {
id: number;
name: string;
avatar: string;
join_date: string;
}
| undefined // fetching user data if exist
| null // user not logged in