├── .eslintrc.json
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── components
├── ConversationBar
│ ├── ConversationBar.js
│ └── index.js
├── InputArea
│ ├── InputArea.js
│ └── index.js
├── Message
│ ├── MessageItem.js
│ ├── MessageList.js
│ └── index.js
└── RoomList
│ ├── RoomList.js
│ └── index.js
├── next.config.js
├── package-lock.json
├── package.json
├── pages
├── _app.js
├── api
│ └── hello.js
├── index.js
└── rooms
│ └── [roomId].js
├── public
├── favicon.ico
└── vercel.svg
├── src
└── sample.aws-exports.js
└── styles
├── Home.module.css
└── globals.css
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
36 | #amplify-do-not-edit-begin
37 | amplify/\#current-cloud-backend
38 | amplify/.config/local-*
39 | amplify/logs
40 | amplify/mock-data
41 | amplify/backend/amplify-meta.json
42 | amplify/backend/.temp
43 | build/
44 | dist/
45 | node_modules/
46 | aws-exports.js
47 | awsconfiguration.json
48 | amplifyconfiguration.json
49 | amplifyconfiguration.dart
50 | amplify-build-config.json
51 | amplify-gradle-config.json
52 | amplifytools.xcconfig
53 | .secret-*
54 | **.sample
55 | #amplify-do-not-edit-end
56 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## Code of Conduct
2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
4 | opensource-codeofconduct@amazon.com with any additional questions or comments.
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
4 | documentation, we greatly value feedback and contributions from our community.
5 |
6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
7 | information to effectively respond to your bug report or contribution.
8 |
9 |
10 | ## Reporting Bugs/Feature Requests
11 |
12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features.
13 |
14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
16 |
17 | * A reproducible test case or series of steps
18 | * The version of our code being used
19 | * Any modifications you've made relevant to the bug
20 | * Anything unusual about your environment or deployment
21 |
22 |
23 | ## Contributing via Pull Requests
24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
25 |
26 | 1. You are working against the latest source on the *main* branch.
27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
29 |
30 | To send us a pull request, please:
31 |
32 | 1. Fork the repository.
33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34 | 3. Ensure local tests pass.
35 | 4. Commit to your fork using clear commit messages.
36 | 5. Send us a pull request, answering any default questions in the pull request interface.
37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
38 |
39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
41 |
42 |
43 | ## Finding contributions to work on
44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
45 |
46 |
47 | ## Code of Conduct
48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
50 | opensource-codeofconduct@amazon.com with any additional questions or comments.
51 |
52 |
53 | ## Security issue notifications
54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
55 |
56 |
57 | ## Licensing
58 |
59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
60 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15 |
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Modern Chat app Frontend
2 |
3 | 🚨 Note that this project does not create our backend services via the Amplify CLI, but relies on exported values from the AWS CDK.
4 |
5 | 🚨 This application is part of a blog post that explains both the frontend and the backend as a whole. The backend repo can be found [here](https://github.com/Focus-Otter/fullstack-cdk-helpers/blob/main/README.md)
6 |
7 | 
8 |
9 | ## Overview
10 |
11 | This repo is the frontend to building a fullstack chat app. The backend can be found [here](https://github.com/Focus-Otter/chat-cdk-backend).
12 |
13 | 
14 |
15 | ## Tech Stack
16 |
17 | - React Framework: NextJS
18 | - UI Library: AWS Amplify UI primitives
19 | - API: GraphQL via AWS AppSync
20 | - File uploads: Sent to Amazon S3
21 | - Signup/SignIn: Managed with Cognito
22 | - Backend Binding: amplify-js
23 |
24 | ## Steps to get started
25 |
26 | Once [the backend ](https://github.com/Focus-Otter/fullstack-cdk-helpers/blob/main/README.md) is deployed, it will output a set of values. The outputted values are what you'll need to get this project working.
27 |
28 | 1. Run `amplify init`
29 | 2. Run `amplify add codegen --apiId YOUR_APPID` (value generated from the backend)
30 | 3. `amplify codegen` (accept the defaults, but set the max-depth to 4)
31 | 4. Create a `src/aws-exports.js` file and bring over the values from your CDK backend and ensure your project looks like the `sample.aws-exports.js` file.
32 | 5. Run the app and create 2 users
33 | 6. Once signed in, create a room.
34 | 7. You should now be able to view the rooms on the homepage. Click one and begin creating messages.
35 |
36 | ## Security
37 |
38 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
39 |
40 | ## License
41 |
42 | This library is licensed under the MIT-0 License. See the LICENSE file.
43 |
--------------------------------------------------------------------------------
/components/ConversationBar/ConversationBar.js:
--------------------------------------------------------------------------------
1 | import { Flex, Menu, useBreakpointValue } from '@aws-amplify/ui-react'
2 | import { useRouter } from 'next/router'
3 | import { useState } from 'react'
4 | import { RoomList } from '../RoomList'
5 |
6 | export const ConversationBar = ({ rooms = [], onRoomChange }) => {
7 | const [isMenuOpen, setIsMenuOpen] = useState(false)
8 | const variation = useBreakpointValue({
9 | base: 'isMobile',
10 | medium: 'isTabletOrHigher',
11 | })
12 | const toggleMenu = (roomId) => {
13 | setIsMenuOpen(false)
14 | onRoomChange(roomId)
15 | }
16 |
17 | const ConversationDisplay = ({ rooms = [] }) => {
18 | if (variation === 'isMobile') {
19 | return (
20 |
21 |
30 |
31 | )
32 | } else if (variation === 'isTabletOrHigher') {
33 | return
34 | }
35 | }
36 | return
37 | }
38 |
--------------------------------------------------------------------------------
/components/ConversationBar/index.js:
--------------------------------------------------------------------------------
1 | export { ConversationBar } from './ConversationBar'
2 |
--------------------------------------------------------------------------------
/components/InputArea/InputArea.js:
--------------------------------------------------------------------------------
1 | import {
2 | Button,
3 | Flex,
4 | TextAreaField,
5 | TextField,
6 | View,
7 | } from '@aws-amplify/ui-react'
8 | import { Storage } from 'aws-amplify'
9 | import { useState } from 'react'
10 |
11 | export const InputArea = ({ onMessageSend }) => {
12 | const [selectedImage, setSelectedImage] = useState(null)
13 | const [messageText, setMessageText] = useState('')
14 |
15 | const uploadFile = async (selectedPic) => {
16 | const { key } = await Storage.put(selectedPic.name, selectedPic, {
17 | contentType: selectedPic.type,
18 | })
19 |
20 | return key
21 | }
22 |
23 | const handleFormSubmit = async (e) => {
24 | e.preventDefault()
25 | let key
26 | if (selectedImage) {
27 | key = await uploadFile(selectedImage)
28 | }
29 |
30 | onMessageSend(messageText, key)
31 | setMessageText('')
32 | }
33 | return (
34 |
40 |
41 |
61 |
62 |
63 | )
64 | }
65 |
--------------------------------------------------------------------------------
/components/InputArea/index.js:
--------------------------------------------------------------------------------
1 | export { InputArea } from './InputArea'
2 |
--------------------------------------------------------------------------------
/components/Message/MessageItem.js:
--------------------------------------------------------------------------------
1 | import {
2 | Card,
3 | Flex,
4 | Heading,
5 | Image,
6 | Text,
7 | useTheme,
8 | View,
9 | } from '@aws-amplify/ui-react'
10 | import { Storage } from 'aws-amplify'
11 | import { useEffect, useState } from 'react'
12 |
13 | export const MessageItem = ({ msg = {}, myUsername }) => {
14 | const { tokens } = useTheme()
15 | if (msg.content.imageId) {
16 | // console.log('the message', msg)
17 | }
18 | const isMyMsg = msg.owner === myUsername
19 | const isEdited = msg.createdAt !== msg.updatedAt
20 |
21 | return (
22 |
29 |
30 |
37 |
38 |
39 |
40 |
41 | {msg.owner}{' '}
42 |
48 | {msg.createdAt}
49 |
50 |
51 |
52 |
53 |
58 |
59 |
60 |
61 |
62 | )
63 | }
64 |
65 | const TextMessage = ({ isMyMsg, msgContent, isEdited }) => {
66 | return (
67 |
68 | {msgContent}{' '}
69 |
70 | )
71 | }
72 |
73 | const PicMessage = ({ msgContent }) => {
74 | const [picUrl, setPicUrl] = useState('')
75 | console.log(msgContent)
76 | useEffect(() => {
77 | Storage.get(msgContent).then((url) => {
78 | console.log(url)
79 | setPicUrl(url)
80 | })
81 | }, [msgContent])
82 | return
83 | }
84 |
--------------------------------------------------------------------------------
/components/Message/MessageList.js:
--------------------------------------------------------------------------------
1 | import { Flex } from '@aws-amplify/ui-react'
2 | import { MessageItem } from './index'
3 |
4 | export const MessageList = ({ messages = [], myUsername }) => {
5 | return (
6 |
13 | {messages.map((msg) => (
14 |
15 | ))}
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/components/Message/index.js:
--------------------------------------------------------------------------------
1 | export { MessageItem } from './MessageItem'
2 | export { MessageList } from './MessageList'
3 |
--------------------------------------------------------------------------------
/components/RoomList/RoomList.js:
--------------------------------------------------------------------------------
1 | import {
2 | Table,
3 | TableBody,
4 | TableCell,
5 | TableHead,
6 | TableRow,
7 | View,
8 | } from '@aws-amplify/ui-react'
9 |
10 | export const RoomList = ({ handleMenuToggle, rooms = [] }) => {
11 | return (
12 |
13 |