sdy
Showing 116 changed files with 2176 additions and 72 deletions
*.xlsx
.env
\ No newline at end of file
# Capstone design
1st semester capstone design project
Subject : Making website in order to practice latest web technologies
sub-subject : making chat site using JS
# Schedule
- 4/6 ~ 4/12
- [x] Set development environment
(tech : react.js, react hooks, styled-components, GraphQL, Prisma, Apollo, AWS, Docker)
- 4/13 ~ 4/19
- [x] login, sign up (using JWT, sendGrid), Create Docker-compose
- 4/20 ~ 4/26
- [ ] Find ID, PW
- 4/27 ~ 5/3
- [ ] Make chat room (using GraphQL's subscription)
- 5/4 ~ 5/10
- [ ] Mid-term exam, Debugging
- 5/11 ~ 5/17
- [ ] Plan chat category and make code
- 5/18 ~ 5/24
- [ ] Debugging for code created in 6th week's plan
- 5/25 ~ 5/31
- [ ] Plan a matching strategy for random chat
- 6/1 ~ 6/7
- [ ] Make a code based on the matching plan created in 8th week's plan
- 6/8 ~ 6/14
- [ ] Debugging for whole codes in our project
- 6/15 ~ 6/21
- [ ] Deploy project in AWS amplify
- 6/22 ~ 6/26
- [ ] Final exam, review project
{
"presets": ["@babel/preset-env"]
}
node_modules
\ No newline at end of file
# node_modules
node_modules
.env
note.txt
linux.txt
\ No newline at end of file
FROM node:12.16.2
RUN npm i -g @prisma/cli
RUN mkdir /app
WORKDIR /app
COPY package*.json ./
COPY prisma ./prisma/
RUN npm install && npx prisma generate
CMD ["npm","start"]
COPY . .
\ No newline at end of file
# Capstone design
1st semester capstone design project
Subject : Making website in order to practice latest web technologies
sub-subject : making chat site using JS
# Schedule
- 4/6 ~ 4/12
- [x] Set development environment
(tech : react.js, react hooks, styled-components, GraphQL, Prisma, Apollo, AWS, Docker)
- 4/13 ~ 4/19
- [x] login, sign up (using JWT, sendGrid), Create Docker-compose
- 4/20 ~ 4/26
- [ ] Find ID, PW
- 4/27 ~ 5/3
- [ ] Make chat room (using GraphQL's subscription)
- 5/4 ~ 5/10
- [ ] Mid-term exam, Debugging
- 5/11 ~ 5/17
- [ ] Plan chat category and make code
- 5/18 ~ 5/24
- [ ] Debugging for code created in 6th week's plan
- 5/25 ~ 5/31
- [ ] Plan a matching strategy for random chat
- 6/1 ~ 6/7
- [ ] Make a code based on the matching plan created in 8th week's plan
- 6/8 ~ 6/14
- [ ] Debugging for whole codes in our project
- 6/15 ~ 6/21
- [ ] Deploy project in AWS amplify
- 6/22 ~ 6/26
- [ ] Final exam, review project
{
"ext": "js graphql"
}
This diff could not be displayed because it is too large.
{
"name": "capstone-back",
"version": "1.0.0",
"description": "1st semester capstone design project",
"scripts": {
"start": "nodemon --exec babel-node src/server.js",
"prisma": "prisma2 studio --experimental"
},
"repository": {
"type": "git",
"url": "git+https://vel1024@bitbucket.org/vel1024/capstone2.git"
},
"author": "sdy, kms",
"license": "ISC",
"homepage": "https://bitbucket.org/vel1024/capstone2#readme",
"dependencies": {
"@prisma/client": "^2.0.0-beta.2",
"bcryptjs": "^2.4.3",
"dotenv": "^8.2.0",
"graphql-tools": "^4.0.7",
"graphql-yoga": "^1.18.3",
"jsonwebtoken": "^8.5.1",
"merge-graphql-schemas": "^1.7.7",
"nodemailer": "^6.4.6",
"nodemailer-sendgrid-transport": "^0.2.0",
"twilio": "^3.42.2"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/node": "^7.8.7",
"@babel/preset-env": "^7.9.0",
"@prisma/cli": "^2.0.0-beta.2",
"morgan": "^1.10.0",
"nodemon": "^2.0.2"
}
}
FROM node:12.16.2
RUN npm i -g @prisma/cli
RUN mkdir /app
WORKDIR /app
COPY ./ ./prisma/
CMD ["prisma", "studio", "--experimental"]
\ No newline at end of file
# Migration `20200419160117-init`
This migration has been generated by sdy at 4/19/2020, 4:01:17 PM.
You can check out the [state of the schema](./schema.prisma) after the migration.
## Database Steps
```sql
CREATE TABLE `chat_schema`.`User` (
`avatarUrl` varchar(191) ,
`bio` varchar(191) ,
`createdAt` datetime DEFAULT CURRENT_TIMESTAMP ,
`email` varchar(191) NOT NULL ,
`id` int NOT NULL AUTO_INCREMENT,
`loginSecret` varchar(191) ,
`name` varchar(191) NOT NULL ,
`password` varchar(191) NOT NULL ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Room` (
`id` int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Category` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(191) DEFAULT '' ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Message` (
`id` int NOT NULL AUTO_INCREMENT,
`senderId` int NOT NULL ,
`text` varchar(191) DEFAULT '' ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`_RoomToUser` (
`A` int NOT NULL ,
`B` int NOT NULL
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`_CategoryToRoom` (
`A` int NOT NULL ,
`B` int NOT NULL
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE UNIQUE INDEX `User.email` ON `chat_schema`.`User`(`email`)
CREATE UNIQUE INDEX `_RoomToUser_AB_unique` ON `chat_schema`.`_RoomToUser`(`A`,`B`)
CREATE INDEX `_RoomToUser_B_index` ON `chat_schema`.`_RoomToUser`(`B`)
CREATE UNIQUE INDEX `_CategoryToRoom_AB_unique` ON `chat_schema`.`_CategoryToRoom`(`A`,`B`)
CREATE INDEX `_CategoryToRoom_B_index` ON `chat_schema`.`_CategoryToRoom`(`B`)
ALTER TABLE `chat_schema`.`Message` ADD FOREIGN KEY (`senderId`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Category`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
DROP TABLE `chat_schema`.`_migration`;
DROP TABLE `chat_schema`.`test`;
```
## Changes
```diff
diff --git schema.prisma schema.prisma
migration ..20200419160117-init
--- datamodel.dml
+++ datamodel.dml
@@ -1,0 +1,41 @@
+generator client {
+ provider = "prisma-client-js"
+ binaryTargets = ["native", "debian-openssl-1.1.x"]
+}
+
+datasource db {
+ provider = "mysql"
+ url = env("DATABASE_URL")
+}
+
+model User {
+ id Int @default(autoincrement()) @id
+ avatarUrl String?
+ email String @unique
+ password String
+ name String
+ loginSecret String?
+ bio String?
+ rooms Room[] @relation(references: [id])
+ messages Message[]
+ createdAt DateTime? @default(now())
+}
+
+model Room {
+ id Int @default(autoincrement()) @id
+ participants User[] @relation(references: [id])
+ categories Category[] @relation(references: [id])
+}
+
+model Category {
+ id Int @default(autoincrement()) @id
+ name String? @default("")
+ rooms Room[] @relation(references: [id])
+}
+
+model Message {
+ id Int @default(autoincrement()) @id
+ text String? @default("")
+ sender User @relation(fields: [senderId], references: [id])
+ senderId Int
+}
```
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-1.1.x"]
}
datasource db {
provider = "mysql"
url = "***"
}
model User {
id Int @default(autoincrement()) @id
avatarUrl String?
email String @unique
password String
name String
loginSecret String?
bio String?
rooms Room[] @relation(references: [id])
messages Message[]
createdAt DateTime? @default(now())
}
model Room {
id Int @default(autoincrement()) @id
participants User[] @relation(references: [id])
categories Category[] @relation(references: [id])
}
model Category {
id Int @default(autoincrement()) @id
name String? @default("")
rooms Room[] @relation(references: [id])
}
model Message {
id Int @default(autoincrement()) @id
text String? @default("")
sender User @relation(fields: [senderId], references: [id])
senderId Int
}
\ No newline at end of file
This diff is collapsed. Click to expand it.
# Migration `20200424124259-init`
This migration has been generated by sdy at 4/24/2020, 12:42:59 PM.
You can check out the [state of the schema](./schema.prisma) after the migration.
## Database Steps
```sql
CREATE TABLE `chat_schema`.`User` (
`avatarUrl` varchar(191) ,
`bio` varchar(191) ,
`createdAt` datetime DEFAULT CURRENT_TIMESTAMP ,
`email` varchar(191) NOT NULL ,
`emailSecret` varchar(191) ,
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(191) NOT NULL ,
`password` varchar(191) NOT NULL ,
`phoneNumber` int ,
`phoneSecret` varchar(191) ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Room` (
`id` int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Category` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(191) DEFAULT '' ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`Message` (
`id` int NOT NULL AUTO_INCREMENT,
`senderId` int NOT NULL ,
`text` varchar(191) DEFAULT '' ,
PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`_RoomToUser` (
`A` int NOT NULL ,
`B` int NOT NULL
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE TABLE `chat_schema`.`_CategoryToRoom` (
`A` int NOT NULL ,
`B` int NOT NULL
)
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
CREATE UNIQUE INDEX `User.email` ON `chat_schema`.`User`(`email`)
CREATE UNIQUE INDEX `_RoomToUser_AB_unique` ON `chat_schema`.`_RoomToUser`(`A`,`B`)
CREATE INDEX `_RoomToUser_B_index` ON `chat_schema`.`_RoomToUser`(`B`)
CREATE UNIQUE INDEX `_CategoryToRoom_AB_unique` ON `chat_schema`.`_CategoryToRoom`(`A`,`B`)
CREATE INDEX `_CategoryToRoom_B_index` ON `chat_schema`.`_CategoryToRoom`(`B`)
ALTER TABLE `chat_schema`.`Message` ADD FOREIGN KEY (`senderId`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_RoomToUser` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`A`) REFERENCES `chat_schema`.`Category`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE `chat_schema`.`_CategoryToRoom` ADD FOREIGN KEY (`B`) REFERENCES `chat_schema`.`Room`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
DROP TABLE `chat_schema`.`_categorytoroom`;
DROP TABLE `chat_schema`.`_migration`;
DROP TABLE `chat_schema`.`_roomtouser`;
DROP TABLE `chat_schema`.`category`;
DROP TABLE `chat_schema`.`message`;
DROP TABLE `chat_schema`.`room`;
DROP TABLE `chat_schema`.`test`;
DROP TABLE `chat_schema`.`user`;
```
## Changes
```diff
diff --git schema.prisma schema.prisma
migration 20200419160117-init..20200424124259-init
--- datamodel.dml
+++ datamodel.dml
@@ -4,18 +4,20 @@
}
datasource db {
provider = "mysql"
- url = "***"
+ url = env("DATABASE_URL")
}
model User {
id Int @default(autoincrement()) @id
avatarUrl String?
email String @unique
password String
name String
- loginSecret String?
+ phoneNumber Int?
+ emailSecret String?
+ phoneSecret String?
bio String?
rooms Room[] @relation(references: [id])
messages Message[]
createdAt DateTime? @default(now())
```
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-1.1.x"]
}
datasource db {
provider = "mysql"
url = "***"
}
model User {
id Int @default(autoincrement()) @id
avatarUrl String?
email String @unique
password String
name String
phoneNumber Int?
emailSecret String?
phoneSecret String?
bio String?
rooms Room[] @relation(references: [id])
messages Message[]
createdAt DateTime? @default(now())
}
model Room {
id Int @default(autoincrement()) @id
participants User[] @relation(references: [id])
categories Category[] @relation(references: [id])
}
model Category {
id Int @default(autoincrement()) @id
name String? @default("")
rooms Room[] @relation(references: [id])
}
model Message {
id Int @default(autoincrement()) @id
text String? @default("")
sender User @relation(fields: [senderId], references: [id])
senderId Int
}
\ No newline at end of file
{
"version": "0.3.14-fixed",
"steps": [
{
"tag": "CreateField",
"model": "User",
"field": "phoneNumber",
"type": "Int",
"arity": "Optional"
},
{
"tag": "CreateField",
"model": "User",
"field": "emailSecret",
"type": "String",
"arity": "Optional"
},
{
"tag": "CreateField",
"model": "User",
"field": "phoneSecret",
"type": "String",
"arity": "Optional"
},
{
"tag": "DeleteField",
"model": "User",
"field": "loginSecret"
}
]
}
\ No newline at end of file
# IF THERE'S A GIT CONFLICT IN THIS FILE, DON'T SOLVE IT MANUALLY!
# INSTEAD EXECUTE `prisma migrate fix`
# Prisma Migrate lockfile v1
# Read more about conflict resolution here: TODO
20200419160117-init
20200424124259-init
\ No newline at end of file
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-1.1.x"]
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model User {
id Int @default(autoincrement()) @id
avatarUrl String?
email String @unique
password String
name String
phoneNumber String? @unique
emailSecret String?
phoneSecret String?
bio String?
rooms Room[] @relation(references: [id])
messages Message[]
createdAt DateTime? @default(now())
}
model Room {
id Int @default(autoincrement()) @id
participants User[] @relation(references: [id])
categories Category[] @relation(references: [id])
}
model Category {
id Int @default(autoincrement()) @id
name String? @default("")
rooms Room[] @relation(references: [id])
}
model Message {
id Int @default(autoincrement()) @id
text String? @default("")
sender User @relation(fields: [senderId], references: [id])
senderId Int
}
\ No newline at end of file
type Mutation {
addCategory(name: String): Category!
}
import { prisma } from "../../../utils";
export default {
Mutation: {
addCategory: async (_, args) => {
const { name } = args;
},
},
};
type Mutation {
deleteCategory(id: String!): Boolean!
}
import { prisma } from "../../../utils";
export default {
Mutation: {
deleteCategory: async (_, args) => {
const { id } = args;
},
},
};
type Mutation {
editCategory(id: String!): Category!
}
import { prisma } from "../../../utils";
export default {
Mutation: {
editCategory: async (_, args) => {
const { id } = args;
},
},
};
type Subscription {
sendMessage(message: String!): Message!
}
import { prisma } from "../../../utils";
export default {
Subscription: {
sendMessage: async (_, args) => {
const { message } = args;
},
},
};
type Mutation {
exitRoom(roomId: String!): Boolean!
}
import { prisma } from "../../../utils";
export default {
Mutation: {
exitRoom: async (_, args) => {
const { roomId } = args;
},
},
};
type Query {
seeRoom(id: String!): Room!
}
import { prisma } from "../../../utils";
export default {
Query: {
seeRoom: async (_, args) => {
const { id } = args;
},
},
};
type Query {
TestQL(text: String!): String!
}
export default {
Query: {
TestQL: async (_, args) => {
const { text } = args;
return text;
},
},
};
type Mutation {
createAccount(
name: String!
email: String!
password: String!
bio: String
avatarUrl: String
): AuthPayload!
}
import { prisma, generateToken } from "../../../utils";
import bcrypt from "bcryptjs";
export default {
Mutation: {
createAccount: async (_, args) => {
const { name, password, email, bio = "", avatarUrl = "" } = args;
const encryptPw = await bcrypt.hash(password, 10);
const user = await prisma.user.create({
data: {
name,
email,
bio,
avatarUrl,
password: encryptPw,
},
});
const token = generateToken(user.id);
return { token, user };
},
},
};
type Mutation {
editProfile(
name: String
email: String
bio: String
avatarUrl: String
): User!
}
import { prisma } from "../../../utils";
export default {
Mutation: {
editProfile: async (_, args, { request }) => {},
},
};
type Query {
findEmail(phoneNumber: String!): User!
}
import { prisma, generateSecret } from "../../../utils";
import twilio from "twilio";
export default {
Query: {
findEmail: async (_, args) => {
const { phoneNumber } = args;
const accountSid = process.env.TWILIO_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = new twilio(accountSid, authToken);
const randomWords = generateSecret();
client.messages
.create({
body: `Please enter this word : ${randomWords}`,
to: `${phoneNumber}`,
from: "KhuChat",
})
.then((message) => console.log(message.sid));
const user = await prisma.user.update({
where: {
phoneNumber,
},
data: {
phoneSecret: randomWords,
},
});
return user;
},
},
};
type Mutation {
login(email: String!, password: String!): AuthPayload
}
import { prisma } from "../../../utils";
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
export default {
Mutation: {
login: async (_, args) => {
const { email, password } = args;
const user = await prisma.user.findOne({
where: {
email,
},
});
let vaild;
if (user) {
vaild = await bcrypt.compare(password, user.password);
}
if (!user || !vaild) {
throw new Error("Not vaild email or password");
}
const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET);
return { token, user };
},
},
};
type Mutation {
requestEmailSecret(email: String!): Boolean!
}
import { prisma, generateSecret, sendSecretMail } from "../../../utils";
import bcrypt from "bcryptjs";
export default {
Mutation: {
requestEmailSecret: async (_, args) => {
const { email } = args;
const emailSecret = generateSecret();
const encryptSecret = await bcrypt.hash(emailSecret, 10);
try {
await sendSecretMail(email, emailSecret);
await prisma.user.update({
where: {
email,
},
data: {
emailSecret: encryptSecret,
},
});
return true;
} catch (error) {
console.log(error);
return false;
}
},
},
};
type Mutation {
resetPassword(
secret: String!
email: String!
passwordOne: String!
passwordTwo: String!
): User!
}
import { prisma } from "../../../utils";
import bcrypt from "bcryptjs";
export default {
Mutation: {
resetPassword: async (_, args) => {
const { secret, email, passwordOne, passwordTwo } = args;
const user = await prisma.user.findOne({
where: {
email,
},
});
const encryptSecret = await bcrypt.hash(user.emailSecret, 10);
if (encryptSecret !== secret) {
throw new Error(
"not vaild secret value!, input another value or resend email"
);
} else {
if (passwordOne !== passwordTwo) {
// For check new password is right, the two things must be same.
throw new Error("the two password don't match each other, try again");
} else {
await prisma.user.update({
where: {
email,
},
data: {
emailSecret: "",
password: passwordOne,
},
});
}
return user;
}
},
},
};
type Query {
searchUser(name: String!): [User!]!
}
import { prisma } from "../../../utils";
export default {
Query: {
searchUser: async (_, args) => {
const { name } = args;
const user = await prisma.user.findOne({});
},
},
};
type Query {
seeProfile(id: String!): User!
}
import { prisma } from "../../../utils";
export default {
Query: {
seeProfile: async (_, args) => {
const { id } = args;
},
},
};
type User {
id: ID!
avatarUrl: String
name: String
email: String!
password: String
phoneNumber: String
emailSecret: String
phoneSecret: String
bio: String
rooms: [Room]
createdAt: String
messages: [Message]
}
type Room {
id: ID!
participants: [User]
categories: [Category]
}
type Category {
id: ID!
name: String
rooms: [Room]
}
type Message {
id: ID!
text: String
sender: User
}
type AuthPayload {
token: String
user: User
}
import path from "path";
import { makeExecutableSchema } from "graphql-tools";
import { fileLoader, mergeResolvers, mergeTypes } from "merge-graphql-schemas";
const allTypes = fileLoader(path.join(__dirname, "api/**/*.graphql"));
const allResolvers = fileLoader(path.join(__dirname, "api/**/*.js"));
const schema = makeExecutableSchema({
typeDefs: mergeTypes(allTypes),
resolvers: mergeResolvers(allResolvers),
});
export default schema;
import dotenv from "dotenv";
dotenv.config();
import { GraphQLServer } from "graphql-yoga";
import morgan from "morgan";
import schema from "./schema";
import { prisma } from "./utils";
const PORT = process.env.PORT;
const server = new GraphQLServer({
schema,
context: (request) => {
return {
...request,
prisma,
};
},
});
server.express.use(morgan("dev"));
server.start(() => console.log(`server is running : http://localhost:${PORT}`));
import { PrismaClient } from "@prisma/client";
import { nouns, adjectives } from "./words";
import jwt from "jsonwebtoken";
import nodemailer from "nodemailer";
import sgTransport from "nodemailer-sendgrid-transport";
export const prisma = new PrismaClient();
export const getUserId = (context) => {
const Authorization = context.request.get("Authorization");
if (Authorization) {
const token = Authorization.replace("Bearer ", "");
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
return userId;
}
throw new Error("There is no vaild user");
};
export const generateSecret = () => {
const randomNumber = Math.floor(Math.random() * adjectives.length);
return `${adjectives[randomNumber]} ${nouns[randomNumber]}`;
};
const sendEmail = (email) => {
const options = {
auth: {
api_user: process.env.SENDGRID_USERNAME,
api_password: process.env.SENDGRID_PASSWORD,
},
};
const client = nodemailer.createTransport(sgTransport(options));
return client.sendMail(email);
};
export const sendSecretMail = (address, emailSecret, value) => {
const email = {
from: "vel1024@khu.ac.kr",
to: address,
subject: `Authentication key for forgotten ${value}`,
html: `Hello, This is khuchat, authentication key is <b>${emailSecret}</b>, copy and paste it, Thanks.`,
};
return sendEmail(email);
};
export const generateToken = (id) => jwt.sign({ id }, process.env.JWT_SECRET);
export const adjectives = [
"languid",
"expensive",
"careful",
"feeble",
"inconclusive",
"damp",
"obscene",
"optimal",
"learned",
"measly",
"silent",
"absurd",
"hypnotic",
"smart",
"horrible",
"deep",
"grotesque",
"rigid",
"sweltering",
"quirky",
"pointless",
"spiffy",
"cheap",
"psychotic",
"possible",
"burly",
"huge",
"tranquil",
"impolite",
"clear",
"groovy",
"royal",
"envious",
"voracious",
"substantial",
"gusty",
"absorbing",
"wealthy",
"fancy",
"ultra",
"giant",
"harmonious",
"nauseating",
"literate",
"friendly",
"panicky",
"utopian",
"happy",
"gaudy",
"direful",
"descriptive",
"better",
"ambiguous",
"momentous",
"obsequious",
"secret",
"clever",
"far",
"temporary",
"unable",
"normal",
"imported",
"three",
"five",
"petite",
"natural",
"early",
"profuse",
"flimsy",
"bustling",
"scrawny",
"present",
"gruesome",
"cut",
"fantastic",
"grandiose",
"second-hand",
"noiseless",
"craven",
"grubby",
"vengeful",
"tiny",
"wiry",
"auspicious",
"dull",
"quiet",
"terrific",
"furry",
"crooked",
"wholesale",
"panoramic",
"forgetful",
"gamy",
"victorious",
"special",
"neighborly",
"useful",
"chubby",
"probable",
"abnormal",
];
export const nouns = [
"rat",
"start",
"icicle",
"hobbies",
"books",
"dress",
"board",
"scale",
"cattle",
"quince",
"cabbage",
"chance",
"attack",
"linen",
"swing",
"skin",
"channel",
"discovery",
"window",
"watch",
"collar",
"creature",
"fall",
"rod",
"skirt",
"trousers",
"guitar",
"pest",
"middle",
"holiday",
"invention",
"pump",
"morning",
"reaction",
"wash",
"cloth",
"hydrant",
"committee",
"meeting",
"star",
"pigs",
"bikes",
"plant",
"stomach",
"transport",
"hole",
"library",
"tank",
"hands",
"offer",
"slip",
"chicken",
"sand",
"wilderness",
"sweater",
"frogs",
"basket",
"flesh",
"cook",
"girl",
"queen",
"nut",
"force",
"laborer",
"basin",
"lumber",
"mine",
"mountain",
"insect",
"store",
"experience",
"credit",
"meat",
"taste",
"iron",
"regret",
"sleep",
"notebook",
"powder",
"fuel",
"lace",
"volleyball",
"look",
"ticket",
"place",
"digestion",
"point",
"crook",
"train",
"judge",
"time",
"truck",
"record",
"sheet",
"join",
"achiever",
"spring",
"death",
"potato",
"liquid",
];
This diff is collapsed. Click to expand it.
version: "3.7"
services:
mysql:
image: mysql:8.0.19
container_name: mysql
ports:
- 3306:3306
restart: always
environment:
MYSQL_DATABASE: prisma
MYSQL_ROOT_PASSWORD: prisma
volumes:
- /var/lib/mysql
prisma:
links:
- mysql
depends_on:
- mysql
container_name: prisma
ports:
- "5555:5555"
build:
context: ./back/prisma
dockerfile: Dockerfile
environment:
MYSQL_URL: ${MYSQL_URL}
MYSQL_DATABASE: prisma
MYSQL_ROOT_PASSWORD: prisma
volumes:
- /app/prisma
backend:
links:
- mysql
depends_on:
- mysql
container_name: backend
ports:
- "4000:4000"
build:
context: ./back
dockerfile: Dockerfile
environment:
MYSQL_URL: ${MYSQL_URL}
FRONTEND_URL: ${FRONTEND_URL}
volumes:
- ./back:/usr/src/app
- ./back/node_modules:/usr/src/app/node_modules
- ./back/prisma:/usr/src/app/prisma
frontend:
container_name: frontend
ports:
- "3000:3000"
tty: "true"
build:
context: ./front
dockerfile: Dockerfile
command: npm start
environment:
- NODE_ENV=development
- CHOKIDAR_USEPOLLING=true
- BACKEND_URL=${BACKEND_URL}
volumes:
- ./front:/usr/src/app
node_modules
\ No newline at end of file
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
FROM node:12.16.2
RUN mkdir /app
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
\ No newline at end of file
# Capstone design
1st semester capstone design project
Subject : Making website in order to practice web tech
sub-subject : making chat site using JS
\ No newline at end of file
This diff could not be displayed because it is too large.
{
"name": "capstone-front",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"apollo-boost": "^0.4.7",
"core-js": "^3.6.5",
"graphql": "^15.0.0",
"react": "^16.13.1",
"react-apollo-hooks": "^0.5.0",
"react-dom": "^16.13.1",
"react-hooks": "^1.0.1",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.1",
"react-toastify": "^5.5.0",
"styled-components": "^5.1.0",
"styled-reset": "^4.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
No preview for this file type
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
import ApolloClient from "apollo-boost";
import { defaults, resolvers } from "./ClientState";
export default new ApolloClient({
uri: "http://localhost:4000",
clientState: {
defaults,
resolvers,
},
});
export const defaults = {};
export const resolvers = {};
import React from "react";
import GlobalStyles from "../Styles/GlobalStyles";
import Header from "./Header";
import Image from "./Image";
import Grid from "./Grid";
export default () => {
return (
<>
<GlobalStyles />
<Header />
<Image />
<Grid />
</>
);
};
import React from "react";
import Styled from "styled-components";
const Article = Styled.div`
width: 70%;
justify-content: center;
align-items: center;
text-align: center;
margin-top: 10px;
border-top: 1px solid black;
`;
export default () => {
return (
<Article>
<h1>Article Title</h1>
</Article>
);
};
import React from "react";
import Styled from "styled-components";
import MenuList from "./MenuList";
import Article from "./Article";
const Grid = Styled.div`
width: 100%;
display: flex;
`;
export default () => {
return (
<Grid>
<MenuList />
<Article />
</Grid>
);
};
import React from "react";
import Styled from "styled-components";
const Header = Styled.div`
width: 100%;
display: flex;
justify-content: center;
margin: 10px 0px;
font-size: 25px;
`;
export default () => {
return (
<Header>
<h1>KHU Chatting service</h1>
</Header>
);
};
import React from "react";
import Styled from "styled-components";
const Image = Styled.div`
width: 100%;
margin: 20px 0px;
display: flex;
justify-content: center;
`;
export default () => {
return (
<Image>
<img src="" alt="sample"></img>
</Image>
);
};
import React from "react";
import Styled from "styled-components";
const MenuBox = Styled.div`
width: 30%;
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
border-top: 1px solid black;
border-right: 1px solid black;
`;
const MenuList = Styled.ol`
`;
const MenuItem = Styled.li`
`;
const Link = Styled.a`
`;
export default () => {
return (
<MenuBox>
<MenuList>
<MenuItem>
<Link href="">1. What is KHU Chat?</Link>
</MenuItem>
</MenuList>
</MenuBox>
);
};
export default {
bgColor: "white",
};
import { createGlobalStyle } from "styled-components";
import reset from "styled-reset";
export default createGlobalStyle`
${reset}
* {
box-sizing: border-box;
}
`;
import React from "react";
import ReactDOM from "react-dom";
import App from "./Components/App";
import { ApolloProvider } from "react-apollo-hooks";
import Client from "./Apollo/Client";
ReactDOM.render(
<ApolloProvider client={Client}>
<App />
</ApolloProvider>,
document.getElementById("root")
);
var Email={
checkEmail:function(self){
var email=document.getElementById('eValidation').value;
var regExp = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/i;
if(regExp.test(email)){
return true;
}else if(email===""){
focusFunction("#eValidation");
alert("이메일을 입력해주세요!");
return false;
}
else {
alert("이메일 형식을 제대로 입력해주세요!");
return false;
}
}
}
var Password={
checkPassword:function(self){
var fpassword=document.getElementById('fValidation').value;
var spassword= document.getElementById('sValidation').value;
if(fpassword==="" || spassword===""){
alert("비밀번호를 입력해주세요!");
return false;
}else if(fpassword===spassword){
return true;
}else{
alert("입력하신 비밀번호들이 다릅니다!");
return false;
}
}
}
function checkValidation(self){
if(Email.checkEmail() && Password.checkPassword() ){
return true;
}else return false;
}
function checkPasswordMatch() {
var password = $("#fpassword").val();
var confirmPassword = $("#spassword").val();
if (password != confirmPassword)
$("#message").html("비밀번호가 일치하지 않습니다.!");
else
$("#message").html("일치.");
}
<!doctype html>
<html>
<head>
<title>KHU KHU Chat</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style/style.css">
<style>
<title>KHU Chat</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style/style.css">
<script src="https://kit.fontawesome.com/6a5db0a2e0.js" crossorigin="anonymous"></script>
<link rel="icon" href="https://kit.fontawesome.com/6a5db0a2e0.js" />
<link href="https://fonts.googleapis.com/css2?family=Black+Han+Sans&display=swap" rel="stylesheet">
<script src="JS/main.js"></script>
</head>
<body>
<header role="banner">
<nav class="khu-nav" role="navigation" aria-label="Primary navigation">
<div class="khu-nav-row">
<div class="khu-logo">
<a id="khu-logo" data-clog-click="" data-clog-ui-element="link_home" href="main.html" aria-label="Khu-logo" data-qa="logo">
<img src="img/Khu_Chat_Icon.svg" width="30px" hegiht="20px" alt="Khu Chat">
</a>
<a id="khu-logo-font" data-clog-click="" data-clog-ui-element="link_home" href="main.html" aria-label="Khu-logo-font" data-qa="logo">
Khu Chat
</a>
</div>
<div class ="khu-login" >
<a data-clog-click="" data-clog-ui-element="link_home" href="main.html" aria-label="Khu-logo-font" data-qa="logo">
Login
</a>
</div>
<div class="khu-signin">
<a data-clog-click="" data-clog-ui-element="link_home" href="main.html" aria-label="Khu-logo-font" data-qa="logo">
Sign in
</a>
</div>
<div class="khu-start-button">
<button id="khu-start-button" onclick="" data-clog-click="" data-clog-ui-element="link_home" href="main.html" aria-label="Khu-start-button" data-qa="logo">
Launch Chating
</button>
</div>
</div>
</nav>
</style>
</head>
<body>
<h1><a href="main.html" color:black>KHU Chatting service</a></h1>
<img src="image/welcome.jpg" class="image">
......@@ -47,11 +16,11 @@
<div id="grid">
<div id="category">
<ol class="center">
<li><a class="dr-icon" href="service/whatiskhuchat.html" >What is KHU chat? </a></li>
<li><a class="dr-icon" href="loginmain.html" >로그인</a></li>
<li><a class="dr-icon" href="signinmain.html" >회원가입</a></li>
<li><a class="dr-icon" href="question.html" >문의사항</a></li>
<li><a class="dr-icon" href="afterlogin.html" >로그인이후</a></li>
<li><a href="service/whatiskhuchat.html" class="saw">What is KHU chat? </a></li>
<li><a href="loginmain.html" class="saw">로그인</a></li>
<li><a href="signinmain.html" class="saw">회원가입</a></li>
<li><a href="question.html" class="saw">문의사항</a></li>
<li><a href="afterlogin.html" class="saw">로그인이후</a></li>
</ol>
</div>
<div id="article">
......@@ -77,5 +46,6 @@
</form>
</div>
</div>
</body>
</html>
......
<!doctype html>
<html>
<head>
<title>KHU KHU Chat</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<script>
function LinksSetColor(color){
var alist=document.querySelectorAll('a');
var i =0;
while(i<alist.length)
{
alist[i].style.color=color;
i+=1;
}
}
var Body={
setColor:function(color){
}
}
function bodySetColor(color){
document.querySelector('body').style.color= color;
}
function bodySetBackGruondColor(color){
document.querySelector('body').style.backgroundColor= color;
}
function nightDayHandler(self){
if(self.value==='night')
{
bodySetBackGruondColor('black')
bodySetColor('white');
self.value= 'day';
setColor('powderblue');
}else{
bodySetBackGruondColor('white')
bodySetColor('black');
self.value= 'night';
setColor('blue');
}
}
</script>
</head>
<body>
<h1><a href="main.html" color:black>KHU Chatting service</a></h1>
<img src="image/signin.jpg" class="image">
<!--refactoring and conditional statement -->
<!-- about this grammer
<input type="button" value="night" onclick="
if(this.value==='night')
{
document.querySelector('body').style.backgroundColor= 'black';
document.querySelector('body').style.color= 'white';
this.value= 'day';
}else{
document.querySelector('body').style.backgroundColor= 'white';
document.querySelector('body').style.color= 'black';
this.value= 'night';
}
">
-->
<!-- about array
<script>
var cowokers=["minsing","minsoft"];
document.write(cowokers[0]);
document.write(cowokers[1]);
cowokers.push("ssssss")
document.write(cowokers);
</script>
-->
<!-- about Loop
<ul>
<script>
var i=0;
while(i<3)
{
document.write("<li>var</li>")
i+=1;
}
</script>
</ul>
-->
<!--Loop & Array
<script>
var cowokers=["minsung","leezche","minsoft","sdy"];
</script>
<script>
var i=0;
while( i< cowokers.length ){
document.write('<li><a href="http://a.com/'+cowokers[i]+'">'+cowokers[i]+'</a></li>');
i+=1;
}
</script>
-->
<!-- Loop apply
var alist=document.querySelectorAll('a');
var i =0;
while(i<alist.length){
console.log(alist[i]);
i+=1;
}
-->
<!-- button 1 usage array and Loop for chage style
self를 통한 input의 객체 지정해주기
지정해주기전에는 전역객체를 가르키게 된다.
-->
<input id="night_day" type="button" value="night" onclick="
nightDayHandler(this);
">
<!-- button2 making and using function -->
<input id="night_day" type="button" value="night" onclick="
nightDayHandler(this);
">
<div id="grid">
<ol>
<li><a href="whatiskhuchat.html" class="saw">What is KHU chat? </a></li>
<li><a href="loginmain.html" class="saw">로그인</a></li>
<li><a href="signinmain.html" class="saw">회원가입</a></li>
<li><a href="question.html" class="saw">문의사항</a></li>
<li><a href="afterlogin.html" class="saw">로그인이후</a></li>
</ol>
<div id="article">
<h2>회원가입</h2>
<div id="inputset">
<form class="signinform" action="loginmain.html">
<label for="email">Email:</label><br>
<input type="text" name="email"><br>
<label for="password">password:</label><br>
<input type="password" name="password"><br>
<label for="name">이름:</label><br>
<input type="text" name="name"><br>
<label for="age">나이:</label><br>
<input type="text" name="age"><br><br>
<label for="sex">성별:</label><br>
<input type="radio" value="man" name="sex">남자<br>
<input type="radio" value="woman" name="sex">여자<br><br>
<label for="work">직업:</label><br>
<input type="radio" value="nowork" name="work">무직<br>
<input type="radio" value="Hstudent" name="work">중/고생<br>
<input type="radio" value="Ustudent" name="work">대학생<br>
<input type="radio" value="worker" name="work">직장인<br><br>
<label for="interesting">관심사(중복선택가능):</label><br>
<input type="checkbox" value="movie" name="interesting">영화<br>
<input type="checkbox" value="song" name="interesting">노래<br>
<input type="checkbox" value="study" name="interesting">공부<br>
<input type="checkbox" value="coding" name="interesting">코딩<br><br>
<input type="submit" value="회원가입신청">
</form>
</div>
</div>
</div>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>KHU chat box model test</title>
<style>
h1,a {
border:5px solid red;
padding:5px;
margin:20px;
width:100px;
}
</style>
</head>
<body>
<h1>Test</h1><br> This is <a href="index.html">test</a> site.
</body>
</html>
var Links={
SetColor:function(color){
// var alist=document.querySelectorAll('a');
// var i =0;
// while(i<alist.length)
// {
// alist[i].style.color=color;
// i+=1;
// }
// }
$('a').css('color',color); //jquery 사용한 것.
}
}
var Body = {
SetColor:function(color){
//document.querySelector('body').style.color= color;
$('body').css('color',color);
},
SetBackGruondColor:function(color){
//document.querySelector('body').style.backgroundColor= color;
$('body').css('backgroundColor',color);
}
}
function nightDayHandler(self){
if(self.value==='night')
{
Body.SetBackGruondColor('black')
Body.SetColor('white');
self.value= 'day';
Links.SetColor('powderblue');
}else{
Body.SetBackGruondColor('white')
Body.SetColor('black');
self.value= 'night';
Links.SetColor('blue');
}
}
<!DOCTYPE html>
<html>
<script src="../fetch-master/fetch.js"></script>
<body>
<input type="button" value="fetch" onclick="
fetch('css').then(function(response){
response.text().then(function(text){
alert(text);
})
});
">
</body>
</html>
<!doctype html>
<html>
<head>
<title>WEB1 - Welcome</title>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="colors.js"></script>
<script src="../fetch-master/fetch.js"></script>
</head>
<body>
<h1><a href="#!welcome">WEB</a></h1>
<h1><a href="index.html">WEB</a></h1>
<h2><a href="welcome.html">Welcome</h2>
<input id="night_day" type="button" value="night" onclick="
nightDayHandler(this);
">
<ol id="nav">
</ol>
<article>
</article>
<script>
function fetchPage(name){
fetch(name).then(function(response){
response.text().then(function(text){
document.querySelector('article').innerHTML=text;
})
});
}
if(location.hash){
fetchPage(location.hash.substr(2));
}else{
fetchPage('welcome');
}
fetch('list').then(function(response){
response.text().then(function(text){
document.querySelector('#nav').innerHTML=text;
})
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#grid{
border-color: pink;
display:grid;
grid-template-columns: 150px 1fr;
}
div{
border:5px solid gray;
}
</style>
</head>
<body>
<div id="grid">
<div>NAVIGATION</div>
<div> ARTICLE</div>
</div>
<!-- div(무생무체와 같은 태그 의미가 없음,디자인 용도)
는 block element span은 inline element -->
</body>
</html>
<!doctype html>
<html>
<head>
<title>WEB - CSS</title>
<meta charset="utf-8">
<style>
body{
margin:0;
}
a {
color:black;
text-decoration: none;
}
h1 {
font-size:45px;
text-align: center;
border-bottom:1px solid gray;
margin:0;
padding:20px;
}
ol{
border-right:1px solid gray;
width:100px;
margin:0;
padding:20px;
}
#grid{
display: grid;
grid-template-columns: 150px 1fr;
}
#grid ol{
padding-left:33px;
}
#grid #article{
padding-left:25px;
}
@media(max-width:800px){
#grid{
display: block;
}
ol{
border-right:none;
}
h1 {
border-bottom:none;
}
}
</style>
</head>
<body>
<h1><a href="index.html">WEB</a></h1>
<div id="grid">
<ol>
<li><a href="1.html">HTML</a></li>
<li><a href="2.html">CSS</a></li>
<li><a href="3.html">JavaScript</a></li>
</ol>
<div id="article">
<h2>CSS</h2>
<p>
Cascading Style Sheets (CSS) is a style sheet language used for describing the presentation of a document written in a markup language.[1] Although most often used to set the visual style of web pages and user interfaces written in HTML and XHTML, the language can be applied to any XML document, including plain XML, SVG and XUL, and is applicable to rendering in speech, or on other media. Along with HTML and JavaScript, CSS is a cornerstone technology used by most websites to create visually engaging webpages, user interfaces for web applications, and user interfaces for many mobile applications.
</p>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>how to make object</h1>
<script>
var coworkers = {
"designer":"minsung",
"programmer":"sdy"
};
document.write("programmer: "+coworkers.programmer+"<br>");
document.write("designer: "+coworkers.designer+"<br>");
coworkers.bookkeeper="duru";
document.write("bookkeeper: "+coworkers.bookkeeper+"<br>");
coworkers["data scientist"] ="taeho";
document.write("data scientist: "+coworkers["data scientist"]+"<br>");
</script>
<h2>iterate</h2>
<h2>property & method</h2>
<script>
coworker.showAll =function(){
for(var key in this){
document.write(key+' : ' +this[key]+'<br>');
}
}
coworkers.showAll();
</script>
</body>
</html>
<!doctype html>
<html>
<head>
<title>KHU KHU Chat</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
//color.js 앞에 jquery 써줘야함
</script>
<script src="colors.js"></script>
</head>
<body>
<input id="night_day" type="button" value="night" onclick="
nightDayHandler(this);
">
<!-- button2 making and using function -->
<input id="night_day" type="button" value="night" onclick="
nightDayHandler(this);
">
<div id="grid">
<ol>
<li><a href="whatiskhuchat.html" class="saw">What is KHU chat? </a></li>
<li><a href="loginmain.html" class="saw">로그인</a></li>
<li><a href="signinmain.html" class="saw">회원가입</a></li>
<li><a href="question.html" class="saw">문의사항</a></li>
<li><a href="afterlogin.html" class="saw">로그인이후</a></li>
</ol>
<div id="article">
<h2>회원가입</h2>
<div id="inputset">
<form class="signinform" action="loginmain.html">
<label for="email">Email:</label><br>
<input type="text" name="email"><br>
<label for="password">password:</label><br>
<input type="password" name="password"><br>
<label for="name">이름:</label><br>
<input type="text" name="name"><br>
<label for="age">나이:</label><br>
<input type="text" name="age"><br><br>
<label for="sex">성별:</label><br>
<input type="radio" value="man" name="sex">남자<br>
<input type="radio" value="woman" name="sex">여자<br><br>
<label for="work">직업:</label><br>
<input type="radio" value="nowork" name="work">무직<br>
<input type="radio" value="Hstudent" name="work">중/고생<br>
<input type="radio" value="Ustudent" name="work">대학생<br>
<input type="radio" value="worker" name="work">직장인<br><br>
<label for="interesting">관심사(중복선택가능):</label><br>
<input type="checkbox" value="movie" name="interesting">영화<br>
<input type="checkbox" value="song" name="interesting">노래<br>
<input type="checkbox" value="study" name="interesting">공부<br>
<input type="checkbox" value="coding" name="interesting">코딩<br><br>
<input type="submit" value="회원가입신청">
</form>
</div>
</div>
</div>
</body>
</html>
......@@ -12,11 +12,11 @@
<div class="media" id="grid">
<div id="category">
<ol class="center">
<li><a class="dr-icon" href="service/whatiskhuchat.html">What is KHU chat? </a></li>
<li><a class="dr-icon"href="loginmain.html" >로그인</a></li>
<li><a class="dr-icon" href="signinmain.html">회원가입</a></li>
<li><a class="dr-icon"href="question.html" >문의사항</a></li>
<li><a class="dr-icon"href="afterlogin.html" >로그인이후</a></li>
<li><a href="service/whatiskhuchat.html" class="saw">What is KHU chat? </a></li>
<li><a href="loginmain.html" class="saw">로그인</a></li>
<li><a href="signinmain.html" class="saw">회원가입</a></li>
<li><a href="question.html" class="saw">문의사항</a></li>
<li><a href="afterlogin.html" class="saw">로그인이후</a></li>
</ol>
</div>
<div id="article">
......
......@@ -4,37 +4,38 @@
<title>KHU KHU Chat</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style/style.css">
<style>
</style>
</head>
<body>
<h1><a href="main.html" color:black>KHU Chatting service</a></h1>
<img src="image/main2.jpg" class="image">
<div id="grid">
<ol>
<li><a href="whatiskhuchat.html" class="saw">What is KHU chat? </a></li>
<div id="grid">
<div id="category">
<ol class="center">
<li><a href="service/whatiskhuchat.html" class="saw">What is KHU chat? </a></li>
<li><a href="loginmain.html" class="saw">로그인</a></li>
<li><a href="signinmain.html" class="saw">회원가입</a></li>
<li><a href="question.html" class="saw">문의사항</a></li>
<li><a href="afterlogin.html" class="saw">로그인이후</a></li>
</ol>
<div id="article">
<h2>로그인 </h2>
<form class="formlogin" action="member.html" id="login">
<label for="email">mail:</label><br>
<input type="text" id="Email" name="email"><br>
<label for="password">password:</label><br>
<input type="password" id="password" name="password"><br><br>
<input type="submit" value="로그인"><br>
</form>
<form class="formlogin" action="signinmain.html" id="signin">
<input type="submit" value="회원가입">
</form>
</div>
<article>
</div>
</article>
<div id="article">
<h2><a href=https://www.helpshift.com/glossary/chat-service/
title="what is chat service">chat service란 무엇인가?</a></h2>
<p>This is chating application which chats with your frineds, coworkers and anyone do you want <br>
so enjoy it out sevice.
</p>
<h2><a href=service/whatiskhuchat.html title="what is KHU chat">
1.What is KHU chat ?</a></h2>
<p>
KHU chat service는 무엇인가요?
</p>
</div>
</div>
</body>
</html>
......
......@@ -13,11 +13,11 @@
<div id="grid">
<div id="category">
<ol class="center">
<li><a class="dr-icon" href="service/whatiskhuchat.html" >What is KHU chat? </a></li>
<li><a class="dr-icon" href="loginmain.html">로그인</a></li>
<li><a class="dr-icon" href="signinmain.html" >회원가입</a></li>
<li><a class="dr-icon" href="question.html" >문의사항</a></li>
<li><a class="dr-icon" href="afterlogin.html" >로그인이후</a></li>
<li><a href="service/whatiskhuchat.html" class="saw">What is KHU chat? </a></li>
<li><a href="loginmain.html" class="saw">로그인</a></li>
<li><a href="signinmain.html" class="saw">회원가입</a></li>
<li><a href="question.html" class="saw">문의사항</a></li>
<li><a href="afterlogin.html" class="saw">로그인이후</a></li>
</ol>
</div>
<div id="article">
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.