This commit is contained in:
Riccardo
2021-01-01 16:50:17 +01:00
parent e87431f64b
commit 129d036f6b
10 changed files with 267 additions and 30 deletions

View File

@@ -6,6 +6,7 @@ import LinkList from './LinkList';
import CreateLink from './CreateLink'
import Header from './Header';
import Login from './Login'
import Search from './Search';
import { Switch, Route } from 'react-router-dom';
const App = () => {
@@ -21,6 +22,7 @@ const App = () => {
component={CreateLink}
/>
<Route exact path="/login" component={Login} />
<Route exact path="/search" component={Search} />
</Switch>
</div>
</div>

View File

@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import { useHistory } from 'react-router';
import { useMutation, gql } from '@apollo/client';
import { FEED_QUERY } from './LinkList';
const CREATE_LINK_MUTATION = gql`
mutation PostMutation(
@@ -28,7 +29,36 @@ const CreateLink = () => {
variables: {
description: formState.description,
url: formState.url
}
},
update: (cache, { data: { post } }) => {
const take = LINKS_PER_PAGE;
const skip = 0;
const orderBy = { createdAt: 'desc' };
const data = cache.readQuery({
query: FEED_QUERY,
variables: {
take,
skip,
orderBy
}
});
cache.writeQuery({
query: FEED_QUERY,
data: {
feed: {
links: [post, ...data.feed.links]
}
},
variables: {
take,
skip,
orderBy
}
});
},
onCompleted: () => history.push('/new/1')
});
return (

View File

@@ -18,12 +18,9 @@ const Header = () => {
top
</Link>
<div className="ml1">|</div>
<Link
to="/search"
className="ml1 no-underline black"
>
<Link to="/search" className="ml1 no-underline black">
search
</Link>
</Link>
{authToken && (
<div className="flex">
<div className="ml1">|</div>

View File

@@ -1,14 +1,104 @@
import React from 'react';
import { useMutation, gql } from '@apollo/client';
import { AUTH_TOKEN, LINKS_PER_PAGE } from '../constants';
import { timeDifferenceForDate } from '../utils'
const VOTE_MUTATION = gql`
mutation VoteMutation($linkId: ID!) {
vote(linkId: $linkId) {
id
link {
id
votes {
id
user {
id
}
}
}
user {
id
}
}
}
`;
const Link = (props) => {
const { link } = props;
const authToken = localStorage.getItem(AUTH_TOKEN);
const take = LINKS_PER_PAGE;
const skip = 0;
const orderBy = { createdAt: 'desc' };
const [vote] = useMutation(VOTE_MUTATION, {
variables: {
linkId: link.id
},
update(cache, { data: { vote } }) {
const { feed } = cache.readQuery({
query: FEED_QUERY
});
const updatedLinks = feed.links.map((feedLink) => {
if (feedLink.id === link.id) {
return {
...feedLink,
votes: [...feedLink.votes, vote]
};
}
return feedLink;
});
cache.writeQuery({
query: FEED_QUERY,
data: {
feed: {
links: updatedLinks
}
}
});
}
});
return (
<div>
<div>
{link.id} - {link.description} ({link.url})
</div>
<div className="flex mt2 items-start">
<div className="flex items-center">
<span className="gray">{props.index + 1}.</span>
{authToken && (
<div
className="ml1 gray f11"
style={{ cursor: 'pointer' }}
onClick={vote}
>
</div>
)}
</div>
<div className="ml1">
<div>
{link.description} ({link.url})
</div>
{authToken && (
<div className="f6 lh-copy gray">
{link.votes.length} votes | by{' '}
{link.postedBy ? link.postedBy.name : 'Unknown'}{' '}
{timeDifferenceForDate(link.createdAt)}
</div>
)}
</div>
</div>
);
};
// const Link = (props) => {
// const { link } = props;
// return (
// <div>
// <div>
// {link.id} - {link.description} ({link.url})
// </div>
// </div>
// );
// };
export default Link;

View File

@@ -1,9 +1,9 @@
import React from 'react';
import Link from './Link';
import { LINKS_PER_PAGE } from '../constants';
import { useQuery, gql } from '@apollo/client';
const FEED_QUERY = gql`
export const FEED_QUERY = gql`
{
feed {
id
@@ -12,25 +12,35 @@ const FEED_QUERY = gql`
createdAt
url
description
postedBy {
id
name
}
votes {
id
user {
id
}
}
}
}
}
`;
const LinkList = () => {
const { data } = useQuery(FEED_QUERY);
const { data } = useQuery(FEED_QUERY);
return (
<div>
{data && (
<>
{data.feed.links.map((link) => (
<Link key={link.id} link={link} />
))}
</>
)}
</div>
);
return (
<div>
{data && (
<>
{data.feed.links.map((link, index) => (
<Link key={link.id} link={link} index={index} />
))}
</>
)}
</div>
);
};
// const LinkList = () => {

View File

@@ -0,0 +1,62 @@
import React, { useState } from 'react';
import { useMutation } from '@apollo/client';
import { useLazyQuery } from '@apollo/client';
import gql from 'graphql-tag';
import Link from './Link';
const FEED_SEARCH_QUERY = gql`
query FeedSearchQuery($filter: String!) {
feed(filter: $filter) {
id
links {
id
url
description
createdAt
postedBy {
id
name
}
votes {
id
user {
id
}
}
}
}
}
`;
const Search = () => {
const [searchFilter, setSearchFilter] = useState('');
const [executeSearch, { data }] = useLazyQuery(
FEED_SEARCH_QUERY
);
return (
<>
<div>
Search
<input
type="text"
onChange={(e) => setSearchFilter(e.target.value)}
/>
<button
onClick={() =>
executeSearch({
variables: { filter: searchFilter }
})
}
>
OK
</button>
</div>
{data &&
data.feed.links.map((link, index) => (
<Link key={link.id} link={link} index={index} />
))}
</>
);
};
export default Search;