Skip to content

AnoushSaroyan/DueMe

Repository files navigation

DueMe

logo

A task Management site where a user can create a team with other users, set projects, and manage tasks.

Technologies

  • MERN (MongoDB, Express, React, and Node)
  • GraphQL
  • AWS
  • Frontend: React/Apollo
  • Backened: MongoDB/Express

Features:

Collapsing components with smooth animations

edit

Get more space to work with by hiding stuff you don't need! These slide out animations are simple that it takes only a few lines of code to implement.

.sidebar{
    transition: margin-left 250ms ease-out,transform 250ms ease-out;
}

.collapsed{
    margin-left: -244px;
}

The collapsed class is removed whenever a component is brought back from being hidden and that is done by a simple repainting of DOM elements.

    handleSidebarHide() {
        const sidebar = document.getElementById("sidebar")
        const headerHam = document.getElementById("main-ham")
        sidebar.classList.add("collapsed")
        headerHam.classList.remove("hidden-ham")
    }

On-the-Fly Editing

edit

Thanks to Apollo/GraphQL's malleable queries and onBlur events, editing can be done in this nature without having to press a submit button.

<Mutation mutation={UPDATE_TASK_TITLE}>
    {(updateTaskTitle, data) => (
            <form
            // the usual submit callback in case the enter key is pressed
            >
                <input
                    value={this.state.title}
                    onChange={this.fieldUpdate("title")}
                    onBlur={e => {
                        e.preventDefault();
                        updateTaskTitle({
                            variables: { id: this.props.task._id, title: this.state.title }
                        }).then(() => this.setState({ editing: false }));
                    }}
                />
            </form>
        </div>
    )}
</Mutation>

The displayed text is updated locally in the component AND a query is sent to have it changed in the database. This saves having to make an unnecessary refetch query.

Real-time Chat

edit

Utilized GraphQL subscriptions to achieve real-time chat functionality. It uses asyncIterator for mapping a subscription to a pubsub channel ( to an event or to many events)

const subscription = new GraphQLObjectType({
    name: "Subscription",
    fields: () => ({
        messageSent: {
            type: ChatType,
            resolve: data => {
                return data.messageSent;
            },  
            subscribe: withFilter(
                () => pubsub.asyncIterator(["MESSAGE_SENT"]),
                () => { return true; } 
            )
        },
        messageDeleted: {
            type: ChatType,
            resolve: data => {
                return data.messageDeleted;
            },
            subscribe: withFilter(
                () => pubsub.asyncIterator(["MESSAGE_DELETED"]),
                () => { return true; }
            )
        }
    })
});

GraphQL Mutation to add a new message to the chat: creates the message and publishes the MESSAGE_SENT event to the chat so the subscribers will get the updated data.

newMessage: {
    type: ChatType,
    args: {
        content: { type: GraphQLString },
        user: { type: GraphQLID },
        chat: { type: GraphQLID }
    },
    async resolve(_, { content, user, chat }, context) {
        let message = new Message({ content, user, chat });
        await message.save();
        let chaty = await Chat.findById(chat);
        if (!chaty.messages.includes(message)) {
            chaty.messages.push(message);
        }
        await chaty.save();
        await pubsub.publish("MESSAGE_SENT", { messageSent: chaty });
        return chaty;
        }
},

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages