├── AngularFront ├── src │ ├── assets │ │ ├── .gitkeep │ │ └── images │ │ │ └── placeholder.png │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── app.config.ts │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ └── app.routes.ts │ ├── components │ │ ├── user-list │ │ │ ├── user-list.component.css │ │ │ ├── user-list.component.html │ │ │ ├── user-list.component.spec.ts │ │ │ └── user-list.component.ts │ │ ├── change-user-info │ │ │ ├── change-user-info.component.css │ │ │ ├── change-user-info.component.spec.ts │ │ │ ├── change-user-info.component.html │ │ │ └── change-user-info.component.ts │ │ ├── main-page │ │ │ ├── main-page.component.html │ │ │ ├── main-page.component.css │ │ │ ├── main-page.component.spec.ts │ │ │ └── main-page.component.ts │ │ ├── header │ │ │ ├── header.component.html │ │ │ ├── header.component.css │ │ │ ├── header.component.spec.ts │ │ │ └── header.component.ts │ │ ├── interest-profile │ │ │ ├── interest-profile.component.html │ │ │ ├── interest-profile.component.css │ │ │ ├── interest-profile.component.spec.ts │ │ │ └── interest-profile.component.ts │ │ ├── user-info-for-list │ │ │ ├── user-info-for-list.component.css │ │ │ ├── user-info-for-list.component.html │ │ │ ├── user-info-for-list.component.spec.ts │ │ │ └── user-info-for-list.component.ts │ │ ├── profile │ │ │ ├── profile.component.html │ │ │ ├── profile.component.spec.ts │ │ │ ├── profile.component.css │ │ │ └── profile.component.ts │ │ ├── interests │ │ │ ├── interests.component.spec.ts │ │ │ ├── interests.component.html │ │ │ ├── interests.component.css │ │ │ └── interests.component.ts │ │ ├── registration │ │ │ ├── registration.component.spec.ts │ │ │ ├── registration.component.css │ │ │ ├── registration.component.html │ │ │ └── registration.component.ts │ │ ├── authorization │ │ │ ├── authorization.component.html │ │ │ ├── authorization.component.spec.ts │ │ │ ├── authorization.component.css │ │ │ └── authorization.component.ts │ │ ├── post-user-info │ │ │ ├── post-user-info.component.spec.ts │ │ │ ├── post-user-info.component.css │ │ │ ├── post-user-info.component.ts │ │ │ └── post-user-info.component.html │ │ └── welcome-information │ │ │ ├── welcome-information.component.spec.ts │ │ │ └── welcome-information.component.ts │ ├── styles.css │ ├── favicon.ico │ ├── DTO │ │ ├── InterestDTO.ts │ │ └── UserInfoDTO.ts │ ├── main.ts │ ├── index.html │ ├── services │ │ ├── user-info │ │ │ ├── user.service.spec.ts │ │ │ └── user.service.ts │ │ ├── interests │ │ │ ├── interests.service.spec.ts │ │ │ └── interests.service.ts │ │ └── authorization │ │ │ ├── authorization.service.spec.ts │ │ │ └── authorization.service.ts │ └── interceptors │ │ └── jwt.interceptor.ts ├── tsconfig.app.json ├── tsconfig.spec.json ├── .editorconfig ├── tsconfig.json ├── README.md ├── package.json └── angular.json ├── frontend ├── src │ ├── components │ │ ├── user-list │ │ │ ├── user-list.css │ │ │ └── user-list.js │ │ ├── App.test.js │ │ ├── user-info-for-list │ │ │ ├── user-info-for-list.css │ │ │ └── user-info-for-list.js │ │ ├── main-page │ │ │ ├── main-page.css │ │ │ └── main-page.js │ │ ├── header │ │ │ ├── header.css │ │ │ └── header.js │ │ ├── App.css │ │ ├── authorization │ │ │ ├── authorization.css │ │ │ └── authorization.js │ │ ├── profile │ │ │ ├── profile.css │ │ │ └── profile.js │ │ ├── registration │ │ │ ├── registration.css │ │ │ └── registration.js │ │ ├── post-user-info │ │ │ ├── post-user-info.css │ │ │ └── post-user-info.js │ │ ├── App.js │ │ ├── interest-profile │ │ │ └── interest-profile.js │ │ └── interests │ │ │ └── interests.css │ ├── setupTests.js │ ├── index.css │ ├── reportWebVitals.js │ ├── index.js │ ├── services │ │ ├── authorizationService.js │ │ ├── userService.js │ │ └── interestService.js │ └── logo.svg ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── index.html ├── .gitignore ├── package.json └── README.md ├── spring.png ├── JSP ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── src │ └── main │ │ ├── webapp │ │ ├── stylesheets │ │ │ ├── userlist.css │ │ │ └── common.css │ │ ├── WEB-INF │ │ │ └── web.xml │ │ ├── addfriend.jsp │ │ ├── index.jsp │ │ ├── userlist.jsp │ │ ├── friends.jsp │ │ ├── sign_in.jsp │ │ ├── registration.jsp │ │ └── profile.jsp │ │ └── resources │ │ └── META-INF │ │ ├── beans.xml │ │ └── persistence.xml └── pom.xml ├── dataAboutDB ├── DBForInternship.drawio.png └── schema ├── JDBC ├── target │ └── classes │ │ ├── org │ │ └── example │ │ │ ├── Main.class │ │ │ └── DBFunctions.class │ │ └── log4j2.xml ├── src │ └── main │ │ ├── java │ │ └── org │ │ │ └── example │ │ │ ├── Main.java │ │ │ ├── data │ │ │ ├── ContactType.java │ │ │ ├── RelationType.java │ │ │ ├── Contact.java │ │ │ ├── Authorization.java │ │ │ ├── Relation.java │ │ │ └── Constants.java │ │ │ ├── DBFunctions.java │ │ │ └── Menu.java │ │ └── resources │ │ └── log4j2.xml └── pom.xml ├── SpringHibernate ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── springhibernate │ │ │ │ ├── service │ │ │ │ ├── ContService.java │ │ │ │ ├── RelService.java │ │ │ │ ├── InterService.java │ │ │ │ ├── UDService.java │ │ │ │ └── impl │ │ │ │ │ ├── ContactService.java │ │ │ │ │ ├── UserService.java │ │ │ │ │ └── AuthenticationService.java │ │ │ │ ├── model │ │ │ │ ├── Role.java │ │ │ │ ├── RelationType.java │ │ │ │ ├── Interest.java │ │ │ │ ├── ContactType.java │ │ │ │ ├── Contact.java │ │ │ │ ├── Pair.java │ │ │ │ ├── UserData.java │ │ │ │ └── Authorization.java │ │ │ │ ├── DTO │ │ │ │ ├── ContactDTO.java │ │ │ │ ├── RelationDTO.java │ │ │ │ ├── InterestDTO.java │ │ │ │ ├── UserDTO.java │ │ │ │ ├── JwtAuthenticationResponse.java │ │ │ │ ├── SignInRequest.java │ │ │ │ └── SignUpRequest.java │ │ │ │ ├── repository │ │ │ │ ├── RelationTypeRepository.java │ │ │ │ ├── InterestRepository.java │ │ │ │ ├── ContactRepository.java │ │ │ │ ├── UserDataRepository.java │ │ │ │ ├── UserRepository.java │ │ │ │ └── PairRepository.java │ │ │ │ ├── SpringHibernateApplication.java │ │ │ │ ├── controller │ │ │ │ ├── RelationController.java │ │ │ │ ├── AuthController.java │ │ │ │ ├── UserDataController.java │ │ │ │ ├── InterestController.java │ │ │ │ └── ContactController.java │ │ │ │ └── JwtAuthenticationFilter.java │ │ └── resources │ │ │ ├── static │ │ │ └── index.html │ │ │ └── application.yaml │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── springhibernate │ │ └── SpringHibernateApplicationTests.java └── .gitignore ├── .idea ├── vcs.xml ├── .gitignore ├── dataSources.xml ├── misc.xml └── encodings.xml ├── .github └── workflows │ └── build.yml ├── .gitignore ├── README.md └── pom.xml /AngularFront/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AngularFront/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/components/user-list/user-list.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AngularFront/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /AngularFront/src/components/user-list/user-list.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AngularFront/src/components/change-user-info/change-user-info.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krilop/PFP-PeopleForPeople/HEAD/spring.png -------------------------------------------------------------------------------- /frontend/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /AngularFront/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /AngularFront/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krilop/PFP-PeopleForPeople/HEAD/AngularFront/src/favicon.ico -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krilop/PFP-PeopleForPeople/HEAD/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krilop/PFP-PeopleForPeople/HEAD/frontend/public/logo192.png -------------------------------------------------------------------------------- /frontend/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krilop/PFP-PeopleForPeople/HEAD/frontend/public/logo512.png -------------------------------------------------------------------------------- /JSP/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krilop/PFP-PeopleForPeople/HEAD/JSP/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /dataAboutDB/DBForInternship.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krilop/PFP-PeopleForPeople/HEAD/dataAboutDB/DBForInternship.drawio.png -------------------------------------------------------------------------------- /AngularFront/src/DTO/InterestDTO.ts: -------------------------------------------------------------------------------- 1 | export interface InterestDTO { 2 | id: number; 3 | titleOfType: string; 4 | icon: string; 5 | } 6 | -------------------------------------------------------------------------------- /JDBC/target/classes/org/example/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krilop/PFP-PeopleForPeople/HEAD/JDBC/target/classes/org/example/Main.class -------------------------------------------------------------------------------- /AngularFront/src/assets/images/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krilop/PFP-PeopleForPeople/HEAD/AngularFront/src/assets/images/placeholder.png -------------------------------------------------------------------------------- /SpringHibernate/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krilop/PFP-PeopleForPeople/HEAD/SpringHibernate/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /JDBC/target/classes/org/example/DBFunctions.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krilop/PFP-PeopleForPeople/HEAD/JDBC/target/classes/org/example/DBFunctions.class -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/service/ContService.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.service; 2 | 3 | public interface ContService { 4 | } 5 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/service/RelService.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.service; 2 | 3 | public interface RelService { 4 | } 5 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/model/Role.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.model; 2 | 3 | public enum Role { 4 | USER_ROLE, 5 | ADMIN_ROLE 6 | } 7 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PFP 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /AngularFront/src/DTO/UserInfoDTO.ts: -------------------------------------------------------------------------------- 1 | export interface UserInfoDTO { 2 | id: number; 3 | name: string; 4 | lastName: string; 5 | description: string; 6 | dateOfBirth: Date; 7 | gender: boolean; 8 | media: string; 9 | age: number; 10 | } 11 | -------------------------------------------------------------------------------- /JSP/src/main/webapp/stylesheets/userlist.css: -------------------------------------------------------------------------------- 1 | .user-info { 2 | width: 80vw; 3 | display: flex; 4 | flex-direction: row; 5 | justify-content: space-evenly; 6 | margin-left: 10%; 7 | margin-right: 10% 8 | } 9 | a{ 10 | margin-top: 0; 11 | } -------------------------------------------------------------------------------- /JSP/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar -------------------------------------------------------------------------------- /frontend/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /JDBC/src/main/java/org/example/Main.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | import java.io.IOException; 3 | import java.sql.SQLException; 4 | 5 | public class Main { 6 | public static void main(String[] args) throws SQLException, IOException { 7 | 8 | Menu.menu(); 9 | } 10 | } -------------------------------------------------------------------------------- /AngularFront/src/main.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapApplication } from '@angular/platform-browser'; 2 | import { appConfig } from './app/app.config'; 3 | import { AppComponent } from './app/app.component'; 4 | 5 | bootstrapApplication(AppComponent, appConfig) 6 | .catch((err) => console.error(err)); 7 | -------------------------------------------------------------------------------- /SpringHibernate/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 3 | -------------------------------------------------------------------------------- /AngularFront/src/components/main-page/main-page.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |

Welcome to PFP - People for People

5 | 6 | 7 |
8 | -------------------------------------------------------------------------------- /frontend/src/components/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/DTO/ContactDTO.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.DTO; 2 | 3 | import lombok.*; 4 | 5 | @Getter 6 | @Setter 7 | @NoArgsConstructor 8 | @AllArgsConstructor 9 | @Builder 10 | public class ContactDTO { 11 | 12 | String info; 13 | 14 | String contactType; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /JSP/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /AngularFront/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /JDBC/src/main/java/org/example/data/ContactType.java: -------------------------------------------------------------------------------- 1 | package org.example.data; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class ContactType { 7 | Long id; 8 | String contactTitle; 9 | 10 | public ContactType(Long id, String contactTitle) { 11 | this.id = id; 12 | this.contactTitle = contactTitle; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /AngularFront/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "include": [ 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /JDBC/src/main/java/org/example/data/RelationType.java: -------------------------------------------------------------------------------- 1 | package org.example.data; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class RelationType { 7 | Long id; 8 | String relationTitle; 9 | 10 | public RelationType(Long id, String relationTitle) { 11 | this.id = id; 12 | this.relationTitle = relationTitle; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /AngularFront/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /JSP/src/main/resources/META-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/DTO/RelationDTO.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.DTO; 2 | 3 | import lombok.*; 4 | 5 | @Getter 6 | @Setter 7 | @NoArgsConstructor 8 | @AllArgsConstructor 9 | @Builder 10 | public class RelationDTO { 11 | 12 | String userName; 13 | String anotherName; 14 | String relationTitle; 15 | } 16 | -------------------------------------------------------------------------------- /AngularFront/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularFront 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/DTO/InterestDTO.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.DTO; 2 | 3 | import lombok.*; 4 | 5 | @Getter 6 | @Setter 7 | @NoArgsConstructor 8 | @AllArgsConstructor 9 | @Builder 10 | public class InterestDTO { 11 | 12 | private Long id; 13 | 14 | private String titleOfType; 15 | 16 | private String icon; 17 | 18 | } -------------------------------------------------------------------------------- /SpringHibernate/src/test/java/com/example/springhibernate/SpringHibernateApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringHibernateApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /AngularFront/src/components/header/header.component.html: -------------------------------------------------------------------------------- 1 |
2 | 10 |
11 | -------------------------------------------------------------------------------- /AngularFront/src/components/interest-profile/interest-profile.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Интересы пользователя

3 |
4 |
5 | Interest 6 |

{{ interest.titleOfType }}

7 |
8 |
9 |
10 | -------------------------------------------------------------------------------- /frontend/.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 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/repository/RelationTypeRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.repository; 2 | 3 | import com.example.springhibernate.model.RelationType; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | @Repository 8 | public interface RelationTypeRepository extends JpaRepository { 9 | } 10 | -------------------------------------------------------------------------------- /frontend/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /frontend/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /JDBC/src/main/java/org/example/data/Contact.java: -------------------------------------------------------------------------------- 1 | package org.example.data; 2 | 3 | import lombok.Data; 4 | @Data 5 | public class Contact { 6 | Long id; 7 | Long userId; 8 | Long contactType; 9 | String info; 10 | 11 | public Contact(Long id, Long userId, Long contactType, String info) { 12 | this.id = id; 13 | this.userId = userId; 14 | this.contactType = contactType; 15 | this.info = info; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /AngularFront/src/services/user-info/user.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { UserService } from './user.service'; 4 | 5 | describe('UserService', () => { 6 | let service: UserService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(UserService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /AngularFront/src/components/user-list/user-list.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 | 6 | 7 |
8 |
9 |
10 |

No users found.

11 |
12 | -------------------------------------------------------------------------------- /JDBC/target/classes/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /JDBC/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /JDBC/src/main/java/org/example/data/Authorization.java: -------------------------------------------------------------------------------- 1 | package org.example.data; 2 | 3 | import lombok.Data; 4 | @Data 5 | public class Authorization { 6 | 7 | Long id; 8 | String login; 9 | String hashOfPass; 10 | String email; 11 | 12 | public Authorization(Long id, String login, String hashOfPass, String email) { 13 | this.id = id; 14 | this.login = login; 15 | this.hashOfPass = hashOfPass; 16 | this.email = email; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /JSP/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/repository/InterestRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.repository; 2 | 3 | import com.example.springhibernate.model.Interest; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | @Repository 8 | public interface InterestRepository extends JpaRepository { 9 | public Boolean existsByTitleOfType(String titleOfType); 10 | } 11 | -------------------------------------------------------------------------------- /AngularFront/src/components/user-info-for-list/user-info-for-list.component.css: -------------------------------------------------------------------------------- 1 | .user-container { 2 | margin-top: 20px; 3 | border: 2px solid #ccc; 4 | border-radius: 15px; 5 | padding: 20px; 6 | } 7 | 8 | .user-info { 9 | display: flex; 10 | } 11 | 12 | .user-avatar { 13 | margin-right: 20px; 14 | } 15 | 16 | .user-avatar img { 17 | width: 100px; 18 | height: 100px; 19 | border-radius: 50%; 20 | } 21 | .error-message { 22 | color: red; 23 | font-weight: bold; 24 | } 25 | -------------------------------------------------------------------------------- /JDBC/src/main/java/org/example/data/Relation.java: -------------------------------------------------------------------------------- 1 | package org.example.data; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class Relation { 7 | 8 | Long id; 9 | Long userId; 10 | Long friendId; 11 | Long relationType; 12 | 13 | public Relation(Long id, Long userId, Long friendId, Long relationType) { 14 | this.id = id; 15 | this.userId = userId; 16 | this.friendId = friendId; 17 | this.relationType = relationType; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/SpringHibernateApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringHibernateApplication { 8 | 9 | public static void main(String[] args) { 10 | 11 | SpringApplication.run(SpringHibernateApplication.class, args); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /AngularFront/src/services/interests/interests.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { InterestsService } from './interests.service'; 4 | 5 | describe('InterestsService', () => { 6 | let service: InterestsService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(InterestsService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /frontend/src/components/user-info-for-list/user-info-for-list.css: -------------------------------------------------------------------------------- 1 | .user-container { 2 | margin-top: 20px; 3 | border: 2px solid #ccc; 4 | border-radius: 15px; 5 | padding: 20px; 6 | } 7 | 8 | .user-info { 9 | display: flex; 10 | } 11 | 12 | .user-avatar { 13 | margin-right: 20px; 14 | } 15 | 16 | .user-avatar img { 17 | width: 100px; 18 | height: 100px; 19 | border-radius: 50%; 20 | } 21 | .error-message { 22 | color: red; 23 | font-weight: bold; 24 | } 25 | -------------------------------------------------------------------------------- /AngularFront/src/components/main-page/main-page.component.css: -------------------------------------------------------------------------------- 1 | 2 | .authentication { 3 | text-align: center; 4 | margin-top: 50px; 5 | } 6 | 7 | h2 { 8 | font-size: 1.8em; 9 | margin-bottom: 20px; 10 | } 11 | 12 | button { 13 | padding: 10px 20px; 14 | font-size: 1.2em; 15 | background-color: #007bff; 16 | color: #fff; 17 | border: none; 18 | border-radius: 5px; 19 | cursor: pointer; 20 | margin-right: 10px; 21 | } 22 | 23 | button:hover { 24 | background-color: #0056b3; 25 | } 26 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/repository/ContactRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.repository; 2 | 3 | import com.example.springhibernate.model.Contact; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | @Repository 10 | public interface ContactRepository extends JpaRepository { 11 | List findContactsByUserDataId(Long id); 12 | } 13 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/repository/UserDataRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.repository; 2 | 3 | import com.example.springhibernate.model.UserData; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.Optional; 8 | @Repository 9 | public interface UserDataRepository extends JpaRepository { 10 | public Optional findUserDataById(Long id); 11 | } 12 | -------------------------------------------------------------------------------- /frontend/src/components/main-page/main-page.css: -------------------------------------------------------------------------------- 1 | 2 | .authentication { 3 | text-align: center; 4 | margin-top: 50px; 5 | } 6 | 7 | h2 { 8 | font-size: 1.8em; 9 | margin-bottom: 20px; 10 | } 11 | 12 | button { 13 | padding: 10px 20px; 14 | font-size: 1.2em; 15 | background-color: #007bff; 16 | color: #fff; 17 | border: none; 18 | border-radius: 5px; 19 | cursor: pointer; 20 | margin-right: 10px; 21 | } 22 | 23 | button:hover { 24 | background-color: #0056b3; 25 | } 26 | -------------------------------------------------------------------------------- /AngularFront/src/services/authorization/authorization.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { AuthorizationService } from './authorization.service'; 4 | 5 | describe('AuthorizationService', () => { 6 | let service: AuthorizationService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(AuthorizationService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /AngularFront/src/app/app.config.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | 4 | import { routes } from './app.routes'; 5 | import {HTTP_INTERCEPTORS, provideHttpClient, withInterceptors} from "@angular/common/http"; 6 | import {JwtInterceptor} from "../interceptors/jwt.interceptor"; 7 | 8 | 9 | 10 | export const appConfig: ApplicationConfig = { 11 | providers: [ 12 | provideRouter(routes), 13 | provideHttpClient(withInterceptors([JwtInterceptor])) 14 | ] 15 | }; 16 | -------------------------------------------------------------------------------- /JDBC/src/main/java/org/example/data/Constants.java: -------------------------------------------------------------------------------- 1 | package org.example.data; 2 | 3 | public class Constants { 4 | private Constants() { 5 | throw new IllegalStateException("Utility class"); 6 | } 7 | public static final String DATABASE_NAME = "PFP"; 8 | public static final String USERNAME = "krimlad"; 9 | public static final String PASSWORD = "krilop"; 10 | public static final String EMAIL = "email"; 11 | public static final String LOGIN = "login"; 12 | public static final String HASH_OF_PASS = "hash_of_pass"; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /SpringHibernate/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/DTO/UserDTO.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.DTO; 2 | 3 | import lombok.*; 4 | 5 | import java.time.LocalDate; 6 | 7 | @Getter 8 | @Setter 9 | @NoArgsConstructor 10 | @AllArgsConstructor 11 | @Builder 12 | public class UserDTO { 13 | 14 | private Long id; 15 | 16 | private String name; 17 | 18 | private String lastName; 19 | 20 | private String description; 21 | 22 | private LocalDate dateOfBirth; 23 | 24 | private boolean gender; 25 | 26 | private String media; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /.idea/dataSources.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | postgresql 6 | true 7 | org.postgresql.Driver 8 | jdbc:postgresql://localhost:5432/PFP 9 | $ProjectFileDir$ 10 | 11 | 12 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.repository; 2 | 3 | import com.example.springhibernate.model.Authorization; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.Optional; 8 | 9 | @Repository 10 | public interface UserRepository extends JpaRepository { 11 | Optional findByLogin(String login); 12 | boolean existsByLogin(String login); 13 | boolean existsByEmail(String email); 14 | } 15 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/service/InterService.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.service; 2 | 3 | import com.example.springhibernate.DTO.InterestDTO; 4 | import com.example.springhibernate.model.Interest; 5 | import org.springframework.http.ResponseEntity; 6 | 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | public interface InterService{ 11 | 12 | ResponseEntity> findAllInterests(); 13 | 14 | ResponseEntity> findInterestById(Long id); 15 | 16 | ResponseEntity createNewInterest(InterestDTO in); 17 | } 18 | -------------------------------------------------------------------------------- /frontend/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /frontend/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './components/App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /AngularFront/src/components/user-info-for-list/user-info-for-list.component.html: -------------------------------------------------------------------------------- 1 |
2 | 13 | 14 |
15 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/DTO/JwtAuthenticationResponse.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.DTO; 2 | 3 | import io.swagger.v3.oas.annotations.media.Schema; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | @Schema(description = "Ответ c токеном доступа") 14 | public class JwtAuthenticationResponse { 15 | @Schema(description = "Токен доступа", example = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTYyMjUwNj...") 16 | private String token; 17 | } -------------------------------------------------------------------------------- /SpringHibernate/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:postgresql://localhost:5432/PFP?stringtype=unspecified 4 | username: krimlad 5 | password: krilop 6 | driver-class-name: org.postgresql.Driver 7 | jpa: 8 | hibernate: 9 | ddl-auto: update 10 | hbm2dll: 11 | auto: validate 12 | database: postgresql 13 | database-platform: org.hibernate.dialect.PostgreSQLDialect 14 | show-sql: true 15 | properties: 16 | hibernate: 17 | format_sql: true 18 | token: 19 | signing: 20 | key: 53A73E5F1C4E0A2D3B5F2D784E6A1B423D6F247D1F6E5C3A596D635A75327855 21 | -------------------------------------------------------------------------------- /AngularFront/src/components/header/header.component.css: -------------------------------------------------------------------------------- 1 | 2 | header { 3 | position: fixed; 4 | top: 0; 5 | left: 0; 6 | width: 100%; 7 | background-color: #333; /* Цвет фона */ 8 | color: #fff; /* Цвет текста */ 9 | padding: 20px 0; /* Внутренний отступ */ 10 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); /* Тень */ 11 | } 12 | 13 | nav ul { 14 | list-style-type: none; 15 | margin: 0; 16 | padding: 0; 17 | } 18 | 19 | nav ul li { 20 | display: inline; 21 | margin-right: 20px; 22 | } 23 | 24 | nav ul li a { 25 | color: #fff; 26 | text-decoration: none; 27 | } 28 | 29 | nav ul li a:hover { 30 | text-decoration: underline; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /AngularFront/src/components/profile/profile.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 14 |
15 | 16 |
17 |
18 | 19 | -------------------------------------------------------------------------------- /JSP/src/main/webapp/addfriend.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="org.example.data.Relation" %> 2 | <%@ page import="java.io.IOException" %> 3 | <%@ page import="java.sql.SQLException" %> 4 | <%@ page import="org.example.crud.CRUDRelation" %> 5 | 6 | <% 7 | String userId = request.getParameter("id"); 8 | String friendId = request.getParameter("friendId"); 9 | String relationType = "1"; 10 | 11 | Relation rel = new Relation(0L, Long.parseLong(userId), Long.parseLong(friendId), Long.parseLong(relationType)); 12 | int status = CRUDRelation.dbSaveRelation(rel); 13 | 14 | if (status == 1) 15 | out.println("Relation saved successfully"); 16 | else 17 | out.println("ERROR while saving relation"); 18 | %> -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/repository/PairRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.repository; 2 | 3 | import com.example.springhibernate.model.Pair; 4 | import com.example.springhibernate.model.UserData; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.List; 9 | 10 | @Repository 11 | public interface PairRepository extends JpaRepository { 12 | public int countByUserId_IdAndAnotherId_Id(Long userId, Long anotherId); 13 | 14 | public Pair findByUserId_IdAndAnotherId_Id(Long userId, Long anotherId); 15 | 16 | public List findPairsByUserId(UserData userId); 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /AngularFront/src/components/header/header.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HeaderComponent } from './header.component'; 4 | 5 | describe('HeaderComponent', () => { 6 | let component: HeaderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [HeaderComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(HeaderComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/src/components/header/header.css: -------------------------------------------------------------------------------- 1 | 2 | header { 3 | position: fixed; 4 | top: 0; 5 | left: 0; 6 | width: 100%; 7 | background-color: #333; /* Цвет фона */ 8 | color: #fff; /* Цвет текста */ 9 | padding: 20px 0; /* Внутренний отступ */ 10 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); /* Тень */ 11 | } 12 | 13 | header nav ul { 14 | list-style-type: none; 15 | margin: 0; 16 | padding: 0; 17 | } 18 | 19 | header nav ul li { 20 | display: inline; 21 | margin-right: 20px; 22 | } 23 | 24 | header nav ul li a { 25 | color: #fff; 26 | text-decoration: none; 27 | } 28 | header button{ 29 | width: 5%; 30 | } 31 | header nav ul li a:hover { 32 | text-decoration: underline; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /AngularFront/src/components/profile/profile.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ProfileComponent } from './profile.component'; 4 | 5 | describe('ProfileComponent', () => { 6 | let component: ProfileComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [ProfileComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(ProfileComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/src/components/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /AngularFront/src/components/main-page/main-page.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { MainPageComponent } from './main-page.component'; 4 | 5 | describe('MainPageComponent', () => { 6 | let component: MainPageComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [MainPageComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(MainPageComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /AngularFront/src/components/main-page/main-page.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {WelcomeInformationComponent} from "../welcome-information/welcome-information.component"; 3 | import {Router} from "@angular/router"; 4 | 5 | @Component({ 6 | selector: 'app-main-page', 7 | standalone: true, 8 | imports: [ 9 | WelcomeInformationComponent 10 | ], 11 | templateUrl: './main-page.component.html', 12 | styleUrl: './main-page.component.css' 13 | }) 14 | export class MainPageComponent { 15 | 16 | constructor(private router:Router) { } 17 | 18 | goToRegistration() { 19 | this.router.navigate(['/auth/sign-up']); 20 | } 21 | 22 | goToAuthentication() { 23 | this.router.navigate(['/auth/sign-in']); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /AngularFront/src/components/user-list/user-list.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { UserListComponent } from './user-list.component'; 4 | 5 | describe('UserListComponent', () => { 6 | let component: UserListComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [UserListComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(UserListComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /AngularFront/src/components/interests/interests.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { InterestsComponent } from './interests.component'; 4 | 5 | describe('InterestsComponent', () => { 6 | let component: InterestsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [InterestsComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(InterestsComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /JSP/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> 2 | 3 | 4 | 5 | 6 | PFP 7 | 8 | 9 | 10 |

<%= "Welcome to our new platform for acquaintances!"%>

11 | <% if(request.getParameter("id")!=null) 12 | {%> 13 | ">Список доступных пользователей 14 | 15 | <%}else{ 16 | %> 17 | Авторизация 18 | Регистрация 19 | 20 | <%}%> 21 | 22 | -------------------------------------------------------------------------------- /AngularFront/src/components/interest-profile/interest-profile.component.css: -------------------------------------------------------------------------------- 1 | .interests-container { 2 | text-align: center; 3 | margin-top: 50px; 4 | } 5 | 6 | .interests-container h1 { 7 | font-size: 24px; 8 | margin-bottom: 20px; 9 | } 10 | 11 | .interests { 12 | display: flex; 13 | flex-wrap: wrap; 14 | justify-content: center; 15 | } 16 | 17 | .interest { 18 | margin: 10px; 19 | width: 100px; 20 | height: 100px; 21 | border: 2px solid #ccc; 22 | border-radius: 50%; 23 | overflow: hidden; 24 | cursor: pointer; 25 | transition: border-color 0.3s, transform 0.3s; 26 | } 27 | 28 | .interest img { 29 | width: 100%; 30 | height: 100%; 31 | object-fit: cover; 32 | } 33 | 34 | .interest:hover { 35 | border-color: #007bff; 36 | transform: scale(1.1); 37 | } 38 | -------------------------------------------------------------------------------- /AngularFront/src/components/registration/registration.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { RegistrationComponent } from './registration.component'; 4 | 5 | describe('RegistrationComponent', () => { 6 | let component: RegistrationComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [RegistrationComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(RegistrationComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/service/UDService.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.service; 2 | 3 | import com.example.springhibernate.DTO.UserDTO; 4 | import com.example.springhibernate.model.UserData; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.http.ResponseEntity; 7 | 8 | import java.util.List; 9 | import java.util.Optional; 10 | 11 | public interface UDService { 12 | 13 | Optional findUserDataById(Long id); 14 | 15 | List findAllUserData(); 16 | 17 | default ResponseEntity createUserDataById(UserDTO in) { 18 | return new ResponseEntity(HttpStatus.UNAUTHORIZED); 19 | } 20 | 21 | void deleteUserDataById(Long id); 22 | 23 | void updateUserData(UserData in); 24 | } 25 | -------------------------------------------------------------------------------- /AngularFront/src/components/authorization/authorization.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Login to PFP - People for People

3 |
4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 | 13 |
14 | {{ errorMessage }} 15 |
16 | 17 |
18 | 19 |
20 | -------------------------------------------------------------------------------- /AngularFront/src/components/post-user-info/post-user-info.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PostUserInfoComponent } from './post-user-info.component'; 4 | 5 | describe('PostUserInfoComponent', () => { 6 | let component: PostUserInfoComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [PostUserInfoComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(PostUserInfoComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /AngularFront/src/components/authorization/authorization.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AuthorizationComponent } from './authorization.component'; 4 | 5 | describe('AuthorizationComponent', () => { 6 | let component: AuthorizationComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [AuthorizationComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(AuthorizationComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /AngularFront/src/components/change-user-info/change-user-info.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ChangeUserInfoComponent } from './change-user-info.component'; 4 | 5 | describe('ChangeUserInfoComponent', () => { 6 | let component: ChangeUserInfoComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [ChangeUserInfoComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(ChangeUserInfoComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /AngularFront/src/components/interest-profile/interest-profile.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { InterestProfileComponent } from './interest-profile.component'; 4 | 5 | describe('InterestProfileComponent', () => { 6 | let component: InterestProfileComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [InterestProfileComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(InterestProfileComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /AngularFront/src/components/user-info-for-list/user-info-for-list.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { UserInfoForListComponent } from './user-info-for-list.component'; 4 | 5 | describe('UserInfoForListComponent', () => { 6 | let component: UserInfoForListComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [UserInfoForListComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(UserInfoForListComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /AngularFront/src/services/user-info/user.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import {HttpClient} from "@angular/common/http"; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class UserService { 8 | apiUrl = "http://localhost:8080/api/v1/PFP"; 9 | constructor(private http:HttpClient) { } 10 | 11 | getUsers() 12 | { 13 | return this.http.get(`${this.apiUrl}/userlist`); 14 | } 15 | 16 | getUser(id:any) 17 | { 18 | return this.http.get(`${this.apiUrl}/profile/${id}/info`); 19 | } 20 | saveUser(user: any) { 21 | return this.http.post(`${this.apiUrl}/profile/${localStorage.getItem('id')}/change`, user); 22 | } 23 | changeUser(user:any){ 24 | return this.http.put(`${this.apiUrl}/profile/${localStorage.getItem('id')}/change`, user); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/model/RelationType.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import jakarta.persistence.*; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | import java.util.List; 9 | 10 | @Entity 11 | @Getter 12 | @Setter 13 | @Table(name = "relation_type") 14 | public class RelationType { 15 | 16 | @Id 17 | @GeneratedValue(strategy = GenerationType.IDENTITY) 18 | private Long id; 19 | 20 | @Column(name = "relation_title", unique = true, nullable = false) 21 | private String relationTitle; 22 | 23 | @JsonIgnore 24 | @ManyToMany(mappedBy = "relationTypes", cascade = { 25 | CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE 26 | }) 27 | private List pairs; 28 | } 29 | -------------------------------------------------------------------------------- /AngularFront/src/components/welcome-information/welcome-information.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { WelcomeInformationComponent } from './welcome-information.component'; 4 | 5 | describe('WelcomeInformationComponent', () => { 6 | let component: WelcomeInformationComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [WelcomeInformationComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(WelcomeInformationComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /AngularFront/src/components/authorization/authorization.component.css: -------------------------------------------------------------------------------- 1 | .auth-container { 2 | text-align: center; 3 | margin-top: 50px; 4 | } 5 | 6 | h2 { 7 | font-size: 1.8em; 8 | margin-bottom: 20px; 9 | } 10 | 11 | .form-group { 12 | margin-bottom: 20px; 13 | } 14 | 15 | label { 16 | display: block; 17 | font-size: 1.2em; 18 | margin-bottom: 5px; 19 | } 20 | 21 | input[type="text"], 22 | input[type="password"] { 23 | width: 300px; 24 | padding: 10px; 25 | font-size: 1em; 26 | } 27 | 28 | button { 29 | padding: 10px 20px; 30 | font-size: 1.2em; 31 | background-color: #007bff; 32 | color: #fff; 33 | border: none; 34 | border-radius: 5px; 35 | cursor: pointer; 36 | } 37 | 38 | button:disabled { 39 | background-color: #ccc; 40 | cursor: not-allowed; 41 | } 42 | 43 | button:hover { 44 | background-color: #0056b3; 45 | } 46 | -------------------------------------------------------------------------------- /AngularFront/src/components/header/header.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {Router, RouterLink} from "@angular/router"; 3 | 4 | @Component({ 5 | selector: 'app-header', 6 | standalone: true, 7 | imports: [ 8 | RouterLink 9 | ], 10 | templateUrl: './header.component.html', 11 | styleUrl: './header.component.css' 12 | }) 13 | export class HeaderComponent { 14 | 15 | constructor(private router:Router) { 16 | } 17 | 18 | logOut() 19 | { 20 | HeaderComponent.logout(this.router); 21 | } 22 | public static logout(router:Router) 23 | { 24 | localStorage.clear(); 25 | router.navigateByUrl('/'); 26 | } 27 | 28 | navigateToProfile(): void { 29 | const userId = localStorage.getItem('id'); // Замените на реальный id пользователя 30 | this.router.navigate(['/profile', userId]); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /JSP/src/main/webapp/stylesheets/common.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | margin-block: 0; 5 | } 6 | 7 | body { 8 | width: 100%; 9 | background-color: #e9e7e7; 10 | font-family: 'Cardo', sans-serif; 11 | color: #232323; 12 | display: flex; 13 | flex-direction: column; 14 | justify-content: center; 15 | align-items: center; 16 | } 17 | 18 | a{ 19 | text-align: center; 20 | margin-top: 24px; 21 | border-width: 3px; 22 | border-style:solid; 23 | padding: 5px; 24 | font-size: 22px; 25 | font-family: Lato, sans-serif; 26 | font-weight: 900; 27 | background-color: #232323; 28 | border-color: #e9e7e7; 29 | border-radius: 5px; 30 | transition: transform 1.5s, color 1.5s, background-color 0.3s; 31 | text-decoration: none; 32 | color: #e9e7e7; 33 | } 34 | p{ 35 | width: 100%; 36 | } -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/model/Interest.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import jakarta.persistence.*; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | import java.util.List; 9 | 10 | @Entity 11 | @Getter 12 | @Setter 13 | @Table(name = "interest") 14 | public class Interest { 15 | 16 | @Id 17 | @GeneratedValue(strategy = GenerationType.IDENTITY) 18 | private Long id; 19 | 20 | @Column(unique = true, name = "title_of_type") 21 | private String titleOfType; 22 | 23 | @Column(name="icon") 24 | private String Icon; 25 | 26 | @JsonIgnore 27 | @ManyToMany(mappedBy = "interests", cascade = { 28 | CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE 29 | }) 30 | private List userDataList; 31 | } 32 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/model/ContactType.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.model; 2 | 3 | public enum ContactType { 4 | PHONE_NUMBER("PHONE_NUMBER"), 5 | TELEGRAM("TELEGRAM"), 6 | SPOTIFY("SPOTIFY"), 7 | INSTAGRAM("INSTAGRAM"); 8 | 9 | private String text; 10 | ContactType(String text) { 11 | this.text = text; 12 | } 13 | 14 | public String getText() { 15 | return text; 16 | } 17 | 18 | // Дополнительный статический метод для получения ContactType из текста 19 | public static ContactType fromText(String text) { 20 | for (ContactType value : ContactType.values()) { 21 | if (value.text.equalsIgnoreCase(text)) { 22 | return value; 23 | } 24 | } 25 | return null; // Возвращаем null, если не найдено совпадение 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /frontend/src/components/authorization/authorization.css: -------------------------------------------------------------------------------- 1 | .auth-container { 2 | text-align: center; 3 | margin-top: 50px; 4 | } 5 | 6 | h2 { 7 | font-size: 1.8em; 8 | margin-bottom: 20px; 9 | } 10 | 11 | .form-group { 12 | margin-bottom: 20px; 13 | } 14 | 15 | label { 16 | display: block; 17 | font-size: 1.2em; 18 | margin-bottom: 5px; 19 | } 20 | 21 | input[type="text"], 22 | input[type="password"] { 23 | width: 300px; 24 | padding: 10px; 25 | font-size: 1em; 26 | } 27 | 28 | button { 29 | padding: 10px 20px; 30 | font-size: 1.2em; 31 | background-color: #007bff; 32 | color: #fff; 33 | border: none; 34 | border-radius: 5px; 35 | cursor: pointer; 36 | } 37 | 38 | button:disabled { 39 | background-color: #ccc; 40 | cursor: not-allowed; 41 | } 42 | 43 | button:hover { 44 | background-color: #0056b3; 45 | } 46 | -------------------------------------------------------------------------------- /frontend/src/components/main-page/main-page.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './main-page.css' 3 | import {useNavigate} from "react-router-dom"; 4 | function MainPageComponent() { 5 | localStorage.clear(); 6 | const navigate = useNavigate(); 7 | const goToRegistration = () => { 8 | navigate('registration'); 9 | }; 10 | 11 | const goToAuthentication = () => { 12 | navigate('authorization'); 13 | }; 14 | 15 | return ( 16 |
17 | 18 | 19 |
20 |

Welcome to PFP - People for People

21 | 22 | 23 |
24 |
25 | ); 26 | } 27 | 28 | export default MainPageComponent; 29 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/model/Contact.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.model; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | 8 | @Entity 9 | @Getter 10 | @Setter 11 | @NoArgsConstructor 12 | @Table(name = "contact") 13 | public class Contact { 14 | 15 | @Id 16 | @GeneratedValue(strategy = GenerationType.IDENTITY) 17 | Long id; 18 | 19 | @Column(nullable = false) 20 | String info; 21 | 22 | @ManyToOne( cascade = { 23 | CascadeType.MERGE, CascadeType.PERSIST 24 | }) 25 | @JoinColumn(name = "user_id", referencedColumnName = "user_id", nullable = false) 26 | private UserData userData; 27 | 28 | @Enumerated(EnumType.STRING) 29 | @Column(name = "contact_type", nullable = false) 30 | private ContactType contactType; 31 | } 32 | -------------------------------------------------------------------------------- /AngularFront/src/components/welcome-information/welcome-information.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-welcome-information', 5 | standalone: true, 6 | imports: [], 7 | template: ` 8 |
9 |

Welcome to PFP - People for People

10 |

We're thrilled to have you join our community!

11 |

Start exploring and connecting with amazing people.

12 |
13 | `, 14 | styles: [ 15 | ` 16 | .welcome-container { 17 | text-align: center; 18 | margin-top: 50px; 19 | } 20 | 21 | h1 { 22 | font-size: 2.5em; 23 | margin-bottom: 20px; 24 | } 25 | 26 | p { 27 | font-size: 1.2em; 28 | margin-bottom: 10px; 29 | } 30 | ` 31 | ] 32 | }) 33 | export class WelcomeInformationComponent { 34 | 35 | } 36 | -------------------------------------------------------------------------------- /AngularFront/src/components/profile/profile.component.css: -------------------------------------------------------------------------------- 1 | /* profile.component.css */ 2 | 3 | .user-container { 4 | margin: 20px; 5 | margin-top: 70px; 6 | padding: 20px; 7 | border: 1px solid #ccc; 8 | border-radius: 5px; 9 | background-color: #f9f9f9; 10 | } 11 | 12 | .user-info { 13 | display: flex; 14 | align-items: center; 15 | } 16 | 17 | .user-avatar { 18 | margin-right: 20px; 19 | } 20 | 21 | .user-avatar img { 22 | width: 100px; /* Размер аватара */ 23 | height: 100px; 24 | border-radius: 50%; /* Закругленные края */ 25 | } 26 | 27 | button { 28 | padding: 10px 20px; 29 | font-size: 1.2em; 30 | background-color: #007bff; 31 | color: #fff; 32 | border: none; 33 | border-radius: 5px; 34 | cursor: pointer; 35 | margin-left: auto; 36 | } 37 | .button-box 38 | { 39 | display: flex; 40 | width: 100%; 41 | } 42 | button:hover { 43 | background-color: #0056b3; 44 | } 45 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/DTO/SignInRequest.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.DTO; 2 | 3 | import io.swagger.v3.oas.annotations.media.Schema; 4 | import jakarta.validation.constraints.NotBlank; 5 | import jakarta.validation.constraints.Size; 6 | import lombok.Data; 7 | 8 | @Data 9 | @Schema(description = "Запрос на аутентификацию") 10 | public class SignInRequest { 11 | 12 | @Schema(description = "Имя пользователя", example = "Jon") 13 | @Size(min = 5, max = 50, message = "Имя пользователя должно содержать от 5 до 50 символов") 14 | @NotBlank(message = "Имя пользователя не может быть пустыми") 15 | private String username; 16 | 17 | @Schema(description = "Пароль", example = "my_1secret1_password") 18 | @Size(min = 8, max = 255, message = "Длина пароля должна быть от 8 до 255 символов") 19 | @NotBlank(message = "Пароль не может быть пустыми") 20 | private String password; 21 | } -------------------------------------------------------------------------------- /AngularFront/src/components/registration/registration.component.css: -------------------------------------------------------------------------------- 1 | 2 | .registration-container { 3 | text-align: center; 4 | margin-top: 50px; 5 | } 6 | 7 | h2 { 8 | font-size: 1.8em; 9 | margin-bottom: 20px; 10 | } 11 | 12 | .form-group { 13 | margin-bottom: 20px; 14 | } 15 | 16 | label { 17 | display: block; 18 | font-size: 1.2em; 19 | margin-bottom: 5px; 20 | } 21 | 22 | input[type="text"], 23 | input[type="email"], 24 | input[type="password"] { 25 | width: 300px; 26 | padding: 10px; 27 | font-size: 1em; 28 | } 29 | 30 | .text-danger { 31 | color: red; 32 | } 33 | 34 | button { 35 | padding: 10px 20px; 36 | font-size: 1.2em; 37 | background-color: #007bff; 38 | color: #fff; 39 | border: none; 40 | border-radius: 5px; 41 | cursor: pointer; 42 | } 43 | 44 | button:disabled { 45 | background-color: #ccc; 46 | cursor: not-allowed; 47 | } 48 | 49 | button:hover { 50 | background-color: #0056b3; 51 | } 52 | -------------------------------------------------------------------------------- /frontend/src/components/profile/profile.css: -------------------------------------------------------------------------------- 1 | /* profile.component.css */ 2 | 3 | .user-container { 4 | margin: 20px; 5 | margin-top: 120px; 6 | padding: 20px; 7 | border: 1px solid #ccc; 8 | border-radius: 5px; 9 | background-color: #f9f9f9; 10 | } 11 | 12 | .user-info { 13 | display: flex; 14 | align-items: center; 15 | } 16 | 17 | .user-avatar { 18 | margin-right: 20px; 19 | } 20 | 21 | .user-avatar img { 22 | width: 100px; /* Размер аватара */ 23 | height: 100px; 24 | border-radius: 50%; /* Закругленные края */ 25 | } 26 | 27 | button { 28 | padding: 10px 20px; 29 | font-size: 1.2em; 30 | background-color: #007bff; 31 | color: #fff; 32 | border: none; 33 | border-radius: 5px; 34 | cursor: pointer; 35 | margin-left: auto; 36 | } 37 | .button-box 38 | { 39 | display: flex; 40 | flex-direction: row; 41 | width: 10%; 42 | } 43 | button:hover { 44 | background-color: #0056b3; 45 | } 46 | -------------------------------------------------------------------------------- /frontend/src/components/registration/registration.css: -------------------------------------------------------------------------------- 1 | 2 | .registration-container { 3 | text-align: center; 4 | margin-top: 50px; 5 | } 6 | 7 | h2 { 8 | font-size: 1.8em; 9 | margin-bottom: 20px; 10 | } 11 | 12 | .form-group { 13 | margin-bottom: 20px; 14 | } 15 | 16 | label { 17 | display: block; 18 | font-size: 1.2em; 19 | margin-bottom: 5px; 20 | } 21 | 22 | input[type="text"], 23 | input[type="email"], 24 | input[type="password"] { 25 | width: 300px; 26 | padding: 10px; 27 | font-size: 1em; 28 | } 29 | 30 | .text-danger { 31 | color: red; 32 | } 33 | 34 | button { 35 | padding: 10px 20px; 36 | font-size: 1.2em; 37 | background-color: #007bff; 38 | color: #fff; 39 | border: none; 40 | border-radius: 5px; 41 | cursor: pointer; 42 | } 43 | 44 | button:disabled { 45 | background-color: #ccc; 46 | cursor: not-allowed; 47 | } 48 | 49 | button:hover { 50 | background-color: #0056b3; 51 | } 52 | -------------------------------------------------------------------------------- /AngularFront/src/components/user-info-for-list/user-info-for-list.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input} from '@angular/core'; 2 | import {UserInfoDTO} from "../../DTO/UserInfoDTO"; 3 | import {DatePipe, NgIf} from "@angular/common"; 4 | import {FormsModule} from "@angular/forms"; 5 | import {Router} from "@angular/router"; 6 | 7 | 8 | @Component({ 9 | selector: 'app-user-info-for-list', 10 | standalone: true, 11 | imports: [ 12 | DatePipe, 13 | FormsModule, 14 | NgIf 15 | ], 16 | templateUrl: './user-info-for-list.component.html', 17 | styleUrl: './user-info-for-list.component.css' 18 | }) 19 | export class UserInfoForListComponent { 20 | @Input() user!: UserInfoDTO; 21 | 22 | constructor(private router:Router){} 23 | 24 | handleImageError(event: any) { 25 | event.target.src = '/assets/images/placeholder.png'; // Путь к запасному изображению 26 | } 27 | 28 | goToProfile(userId: number): void { 29 | this.router.navigate(['/profile', userId]); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /AngularFront/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "outDir": "./dist/out-tsc", 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "skipLibCheck": true, 12 | "esModuleInterop": true, 13 | "sourceMap": true, 14 | "declaration": false, 15 | "experimentalDecorators": true, 16 | "moduleResolution": "node", 17 | "importHelpers": true, 18 | "target": "ES2022", 19 | "module": "ES2022", 20 | "useDefineForClassFields": false, 21 | "lib": [ 22 | "ES2022", 23 | "dom" 24 | ] 25 | }, 26 | "angularCompilerOptions": { 27 | "enableI18nLegacyMessageIdFormat": false, 28 | "strictInjectionParameters": true, 29 | "strictInputAccessModifiers": true, 30 | "strictTemplates": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /AngularFront/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async () => { 6 | await TestBed.configureTestingModule({ 7 | imports: [AppComponent], 8 | }).compileComponents(); 9 | }); 10 | 11 | it('should create the app', () => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.componentInstance; 14 | expect(app).toBeTruthy(); 15 | }); 16 | 17 | it(`should have the 'AngularFront' title`, () => { 18 | const fixture = TestBed.createComponent(AppComponent); 19 | const app = fixture.componentInstance; 20 | expect(app.title).toEqual('AngularFront'); 21 | }); 22 | 23 | it('should render title', () => { 24 | const fixture = TestBed.createComponent(AppComponent); 25 | fixture.detectChanges(); 26 | const compiled = fixture.nativeElement as HTMLElement; 27 | expect(compiled.querySelector('h1')?.textContent).toContain('Hello, AngularFront'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "axios": "^1.6.8", 10 | "jwt-decode": "^4.0.0", 11 | "react": "^18.2.0", 12 | "react-dom": "^18.2.0", 13 | "react-router-dom": "^6.22.3", 14 | "react-scripts": "^5.0.1", 15 | "web-vitals": "^2.1.4" 16 | }, 17 | "scripts": { 18 | "start": "react-scripts start", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": [ 25 | "react-app", 26 | "react-app/jest" 27 | ] 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.2%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 17 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /JDBC/src/main/java/org/example/DBFunctions.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | 6 | import java.sql.Connection; 7 | import java.sql.DriverManager; 8 | import java.sql.SQLException; 9 | 10 | public class DBFunctions { 11 | private static final Logger logger = LogManager.getLogger(DBFunctions.class); 12 | public Connection connectToDB(String dbname, String user, String password) throws SQLException { 13 | Connection conn = null; 14 | try { 15 | Class.forName("org.postgresql.Driver"); 16 | } catch (ClassNotFoundException e) { 17 | throw new SQLException(e); 18 | } 19 | try{ 20 | conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/"+dbname,user,password); 21 | logger.info("Successfully connect!"); 22 | } 23 | catch (Exception e) 24 | { 25 | logger.info("Cannot connect to Database!"); 26 | logger.error(e); 27 | } 28 | return conn; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /frontend/src/components/header/header.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './header.css'; 3 | import { Link, useNavigate } from "react-router-dom"; 4 | 5 | function Header() { 6 | const navigate = useNavigate(); 7 | 8 | const navigateToProfile = () => { 9 | // Ваша логика перехода на страницу профиля 10 | navigate(`/profile/${localStorage.getItem('id')}`); 11 | }; 12 | 13 | const logOut = () => { 14 | localStorage.clear(); 15 | navigate('/'); // Используйте navigate для перехода на главную страницу 16 | }; 17 | 18 | return ( 19 |
20 | 28 |
29 | ); 30 | } 31 | 32 | export default Header; 33 | -------------------------------------------------------------------------------- /frontend/src/components/user-info-for-list/user-info-for-list.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {useNavigate} from "react-router-dom"; 3 | 4 | function UserInfoForListComponent({ user }) { 5 | 6 | const navigate = useNavigate() 7 | const goToProfile = (userId) => { 8 | navigate(`/profile/${userId}`); 9 | }; 10 | 11 | return ( 12 |
13 |
14 |
15 | NO_PHOTO 16 |
17 |
18 |

{ user.name } { user.lastName }

19 |

{ user.description }

20 |

Возраст: { user.age }

21 |

Пол: { user.gender ? 'Мужской' : 'Женский' }

22 |
23 |
24 | 25 |
26 | ); 27 | } 28 | 29 | export default UserInfoForListComponent; 30 | -------------------------------------------------------------------------------- /AngularFront/src/components/registration/registration.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Register on PFP - People for People

3 |
4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 | {{ getEmailErrorMessage() }} 13 |
14 |
15 |
16 | 17 | 18 |
19 | 20 |
21 |
22 | -------------------------------------------------------------------------------- /AngularFront/src/services/interests/interests.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import {HttpClient} from "@angular/common/http"; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class InterestsService { 8 | 9 | apiUrl = "http://localhost:8080/api/v1/PFP"; 10 | constructor(private http:HttpClient) { } 11 | 12 | getInterests() 13 | { 14 | return this.http.get(`${this.apiUrl}/interests/all`); 15 | } 16 | 17 | getInterestsForUser() 18 | { 19 | return this.http.get(`${this.apiUrl}/interests/${localStorage.getItem('id')}/new`); 20 | } 21 | getInterestsOfUser(id:string) 22 | { 23 | return this.http.get(`${this.apiUrl}/interests/${id}`); 24 | } 25 | deleteInterestOfUser(id:number) 26 | { 27 | return this.http.delete(`${this.apiUrl}/interests/${localStorage.getItem('id')}/${id}`); 28 | } 29 | saveInterest(interest: any) { 30 | return this.http.post(`${this.apiUrl}/interests/addNew`, interest); 31 | } 32 | addInterestForUser(id:number) { 33 | return this.http.post(`${this.apiUrl}/interests/${localStorage.getItem('id')}/${id}`,''); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /AngularFront/src/components/interest-profile/interest-profile.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {InterestsService} from "../../services/interests/interests.service"; 3 | import {InterestDTO} from "../../DTO/InterestDTO"; 4 | import {CommonModule} from "@angular/common"; 5 | import {ActivatedRoute, Route} from "@angular/router"; 6 | 7 | @Component({ 8 | selector: 'app-interest-profile', 9 | standalone: true, 10 | imports: [CommonModule], 11 | templateUrl: './interest-profile.component.html', 12 | styleUrl: './interest-profile.component.css' 13 | }) 14 | export class InterestProfileComponent implements OnInit { 15 | interests: InterestDTO[] = []; 16 | userId: string = ''; 17 | 18 | constructor(private interestsService: InterestsService, private route: ActivatedRoute) {} 19 | 20 | ngOnInit(): void { 21 | this.route.params.subscribe(params => { 22 | this.userId = params['id']; 23 | this.getInterests(); 24 | }); 25 | } 26 | 27 | getInterests(): void { 28 | this.interestsService.getInterestsOfUser(this.userId).subscribe(interests => { 29 | this.interests = interests; 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /AngularFront/README.md: -------------------------------------------------------------------------------- 1 | # AngularFront 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.3.3. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. 28 | -------------------------------------------------------------------------------- /AngularFront/src/components/user-list/user-list.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {UserInfoDTO} from "../../DTO/UserInfoDTO"; 3 | import {UserService} from "../../services/user-info/user.service"; 4 | import {UserInfoForListComponent} from "../user-info-for-list/user-info-for-list.component"; 5 | import {CommonModule} from "@angular/common"; 6 | import {HeaderComponent} from "../header/header.component"; 7 | @Component({ 8 | selector: 'app-user-list', 9 | standalone: true, 10 | imports: [ 11 | UserInfoForListComponent, CommonModule, HeaderComponent 12 | ], 13 | templateUrl: './user-list.component.html', 14 | styleUrl: './user-list.component.css' 15 | }) 16 | export class UserListComponent implements OnInit { 17 | userList: UserInfoDTO[] | undefined; 18 | id:any; 19 | constructor(private userService: UserService) {} 20 | 21 | ngOnInit(): void { 22 | this.loadUsers(); 23 | this.id = localStorage.getItem('id'); 24 | } 25 | 26 | loadUsers(): void { 27 | this.userService.getUsers().subscribe( 28 | users => { 29 | this.userList = users; 30 | }, 31 | error => { 32 | console.error('Error loading users:', error); 33 | } 34 | ); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /AngularFront/src/components/post-user-info/post-user-info.component.css: -------------------------------------------------------------------------------- 1 | .form-container { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | height: 100vh; 6 | } 7 | 8 | .form-table { 9 | width: 400px; 10 | border-collapse: collapse; 11 | border-spacing: 0; 12 | } 13 | 14 | .form-group { 15 | display: flex; 16 | flex-direction: column; 17 | margin-bottom: 20px; 18 | } 19 | 20 | label { 21 | font-weight: bold; 22 | } 23 | 24 | input[type="text"], 25 | select { 26 | width: calc(100% - 20px); 27 | padding: 10px; 28 | font-size: 16px; 29 | border-radius: 5px; 30 | border: 1px solid #ccc; 31 | } 32 | textarea 33 | { 34 | width: calc(100% - 20px); 35 | padding: 10px; 36 | font-size: 16px; 37 | border-radius: 5px; 38 | border: 1px solid #ccc; 39 | } 40 | 41 | select { 42 | width: 100%; 43 | } 44 | 45 | button { 46 | width: 100%; 47 | padding: 10px 20px; 48 | font-size: 16px; 49 | background-color: #007bff; 50 | color: #fff; 51 | border: none; 52 | border-radius: 5px; 53 | cursor: pointer; 54 | } 55 | 56 | img { 57 | width: 100%; /* Размер аватара */ 58 | height: auto; 59 | border-radius: 50%; /* Закругленные края */ 60 | } 61 | button:hover { 62 | background-color: #0056b3; 63 | } 64 | -------------------------------------------------------------------------------- /JSP/src/main/webapp/userlist.jsp: -------------------------------------------------------------------------------- 1 | <%@page import="org.example.crud.CRUDAuthorization" %> 2 | <%@page import="org.example.data.Authorization" %> 3 | <%@page import="java.util.List" %> 4 | <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> 5 | 6 | 7 | 8 | 9 | PFP 10 | 11 | 12 | 13 | 14 | 15 |

<%= "List of available users:"%>

16 | <% 17 | List users = CRUDAuthorization.dbGetAllUsers(); 18 | for (Authorization user: users) { 19 | if(user.getId()!= Long.parseLong(request.getParameter("id"))){ 20 | %> 21 | 30 | <% }} %> 31 | 32 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/DTO/SignUpRequest.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.DTO; 2 | 3 | import io.swagger.v3.oas.annotations.media.Schema; 4 | import jakarta.validation.constraints.Email; 5 | import jakarta.validation.constraints.NotBlank; 6 | import jakarta.validation.constraints.Size; 7 | import lombok.Data; 8 | 9 | @Data 10 | @Schema(description = "Запрос на регистрацию") 11 | public class SignUpRequest { 12 | 13 | @Schema(description = "Имя пользователя", example = "Jon") 14 | @Size(min = 5, max = 50, message = "Имя пользователя должно содержать от 5 до 50 символов") 15 | @NotBlank(message = "Имя пользователя не может быть пустыми") 16 | private String username; 17 | 18 | @Schema(description = "Адрес электронной почты", example = "jondoe@gmail.com") 19 | @Size(min = 5, max = 255, message = "Адрес электронной почты должен содержать от 5 до 255 символов") 20 | @NotBlank(message = "Адрес электронной почты не может быть пустыми") 21 | @Email(message = "Email адрес должен быть в формате user@example.com") 22 | private String email; 23 | 24 | @Schema(description = "Пароль", example = "my_1secret1_password") 25 | @Size(max = 255, message = "Длина пароля должна быть не более 255 символов") 26 | private String password; 27 | } 28 | -------------------------------------------------------------------------------- /frontend/src/components/post-user-info/post-user-info.css: -------------------------------------------------------------------------------- 1 | .form-container { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | height: 100vh; 6 | } 7 | 8 | .form-table { 9 | width: 400px; 10 | border-collapse: collapse; 11 | border-spacing: 0; 12 | } 13 | 14 | .form-group { 15 | display: flex; 16 | flex-direction: column; 17 | margin-bottom: 20px; 18 | } 19 | 20 | label { 21 | font-weight: bold; 22 | } 23 | 24 | input[type="text"], 25 | select { 26 | width: calc(100% - 20px); 27 | padding: 10px; 28 | font-size: 16px; 29 | border-radius: 5px; 30 | border: 1px solid #ccc; 31 | } 32 | textarea 33 | { 34 | width: calc(100% - 20px); 35 | padding: 10px; 36 | font-size: 16px; 37 | border-radius: 5px; 38 | border: 1px solid #ccc; 39 | } 40 | 41 | select { 42 | width: 100%; 43 | } 44 | 45 | button { 46 | width: 100%; 47 | padding: 10px 20px; 48 | font-size: 16px; 49 | background-color: #007bff; 50 | color: #fff; 51 | border: none; 52 | border-radius: 5px; 53 | cursor: pointer; 54 | } 55 | 56 | img { 57 | width: 100%; /* Размер аватара */ 58 | height: auto; 59 | border-radius: 50%; /* Закругленные края */ 60 | } 61 | button:hover { 62 | background-color: #0056b3; 63 | } 64 | -------------------------------------------------------------------------------- /AngularFront/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-front", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "watch": "ng build --watch --configuration development", 9 | "test": "ng test" 10 | }, 11 | "private": true, 12 | "dependencies": { 13 | "@angular/animations": "^17.3.0", 14 | "@angular/common": "^17.3.0", 15 | "@angular/compiler": "^17.3.0", 16 | "@angular/core": "^17.3.0", 17 | "@angular/forms": "^17.3.0", 18 | "@angular/platform-browser": "^17.3.0", 19 | "@angular/platform-browser-dynamic": "^17.3.0", 20 | "@angular/router": "^17.3.0", 21 | "@auth0/angular-jwt": "^5.2.0", 22 | "jwt-decode": "^4.0.0", 23 | "jwt-simple": "^0.5.6", 24 | "rxjs": "~7.8.0", 25 | "tslib": "^2.3.0", 26 | "zone.js": "~0.14.3" 27 | }, 28 | "devDependencies": { 29 | "@angular-devkit/build-angular": "^17.3.3", 30 | "@angular/cli": "^17.3.3", 31 | "@angular/compiler-cli": "^17.3.0", 32 | "@types/jasmine": "~5.1.0", 33 | "@types/jwt-decode": "^3.1.0", 34 | "jasmine-core": "~5.1.0", 35 | "karma": "~6.4.0", 36 | "karma-chrome-launcher": "~3.2.0", 37 | "karma-coverage": "~2.2.0", 38 | "karma-jasmine": "~5.1.0", 39 | "karma-jasmine-html-reporter": "~2.1.0", 40 | "typescript": "~5.4.2" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /AngularFront/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, inject} from '@angular/core'; 2 | import {RouterOutlet} from '@angular/router'; 3 | import {AuthorizationComponent} from "../components/authorization/authorization.component"; 4 | import {WelcomeInformationComponent} from "../components/welcome-information/welcome-information.component"; 5 | import {FormsModule} from "@angular/forms"; 6 | import {HttpClient, HttpClientModule} from "@angular/common/http"; 7 | import {CommonModule} from '@angular/common'; 8 | import {PostUserInfoComponent} from "../components/post-user-info/post-user-info.component"; 9 | import {InterestsComponent} from "../components/interests/interests.component"; 10 | import {InterestProfileComponent} from "../components/interest-profile/interest-profile.component"; 11 | import {ChangeUserInfoComponent} from "../components/change-user-info/change-user-info.component"; // Import CommonModule 12 | 13 | @Component({ 14 | selector: 'app-root', 15 | standalone: true, 16 | imports: [RouterOutlet, AuthorizationComponent, WelcomeInformationComponent, PostUserInfoComponent, FormsModule, HttpClientModule, CommonModule, InterestsComponent, InterestProfileComponent, ChangeUserInfoComponent], 17 | templateUrl: './app.component.html', 18 | styleUrl: './app.component.css' 19 | }) 20 | export class AppComponent { 21 | title = 'AngularFront'; 22 | } 23 | -------------------------------------------------------------------------------- /AngularFront/src/components/authorization/authorization.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {FormsModule} from "@angular/forms"; 3 | import {AuthorizationService} from "../../services/authorization/authorization.service"; 4 | import {Router} from "@angular/router"; 5 | import {CommonModule} from "@angular/common"; 6 | 7 | 8 | @Component({ 9 | selector: 'app-authorization', 10 | standalone: true, 11 | imports: [ 12 | FormsModule,CommonModule 13 | ], 14 | templateUrl:'authorization.component.html', 15 | styleUrl: 'authorization.component.css' 16 | }) 17 | export class AuthorizationComponent { 18 | username: string = ''; 19 | password: string = ''; 20 | errorMessage: any; 21 | 22 | constructor( 23 | private router: Router, 24 | private authorizationService: AuthorizationService 25 | ) {} 26 | 27 | login() { 28 | this.authorizationService.login(this.username, this.password) 29 | .subscribe( 30 | response => { 31 | // Переадресация на страницу /userlist после успешной аутентификации 32 | this.router.navigate(['/userlist']); 33 | }, 34 | error => { 35 | // Сохраняем сообщение об ошибке 36 | alert('Ошибка аутентификации. Проверьте введенные данные.') 37 | console.error('Login error', error); 38 | } 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /AngularFront/src/interceptors/jwt.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { 2 | HttpResponse, HttpErrorResponse, HttpInterceptorFn 3 | } from '@angular/common/http'; 4 | import {Observable, tap} from 'rxjs'; 5 | import * as jwt_decode from 'jwt-decode'; 6 | 7 | export const JwtInterceptor: HttpInterceptorFn = (req, next) => { 8 | // Получаем токен из локального хранилища 9 | console.log('Intercepted request:', req); 10 | const jwtToken = localStorage.getItem('jwtToken'); 11 | 12 | if (jwtToken) { 13 | console.log(jwtToken); 14 | if (!localStorage.getItem('id')) { 15 | const decodedToken: any = jwt_decode.jwtDecode(jwtToken); 16 | localStorage.setItem('id', decodedToken.id); 17 | console.log(localStorage.getItem('id')); 18 | } 19 | 20 | // Добавляем токен в заголовок Authorization 21 | req = req.clone({ 22 | setHeaders: { 23 | 'Content-Type': 'application/json', 24 | 'Authorization': `Bearer ${jwtToken}` 25 | } 26 | }); 27 | } 28 | 29 | return next(req).pipe( 30 | tap( 31 | (event) => { 32 | if (event instanceof HttpResponse) 33 | console.log('Server response'); 34 | }, 35 | (err) => { 36 | if (err instanceof HttpErrorResponse) { 37 | if (err.status == 401) 38 | console.log('Unauthorized'); 39 | } 40 | } 41 | ) 42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /AngularFront/src/components/interests/interests.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Выберите ваши интересы

3 |
4 |
5 | Interest 6 |
7 |
8 |
9 |
10 |

Не нашел своего интереса? ДОБАВЬ СВОЙ!

11 |
12 |
13 | 14 | 15 |
16 | Interest Preview 17 |
18 |
19 |
20 | 21 | 22 |
23 | 24 |
25 |
26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /frontend/src/services/authorizationService.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import {jwtDecode} from "jwt-decode"; 3 | 4 | class AuthorizationService { 5 | apiUrl = 'http://localhost:8080/auth'; 6 | 7 | async login(username, password) { 8 | try { 9 | const response = await axios.post(`${this.apiUrl}/sign-in`, {username, password}); 10 | // Сохраняем токен в локальное хранилище 11 | localStorage.setItem('token', response.data.token); 12 | const decodedToken = jwtDecode(response.data.token); 13 | localStorage.setItem('id', decodedToken.id); 14 | console.log(localStorage.getItem('token')) 15 | return response.data; 16 | } catch (error) { 17 | throw error; 18 | } 19 | } 20 | 21 | async register(username, email, password) { 22 | try { 23 | const response = await axios.post(`${this.apiUrl}/sign-up`, {username, email, password}); 24 | // Сохраняем токен в локальное хранилище 25 | localStorage.setItem('token', response.data.token); 26 | const decodedToken = jwtDecode(response.data.token); 27 | localStorage.setItem('id', decodedToken.id); 28 | return response.data; 29 | } catch (error) { 30 | throw error; 31 | } 32 | } 33 | } 34 | 35 | export default new AuthorizationService(); 36 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: SonarCloud 2 | on: 3 | push: 4 | branches: 5 | - main 6 | - develop 7 | pull_request: 8 | types: [opened, synchronize, reopened] 9 | jobs: 10 | build: 11 | name: Build and analyze 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | with: 16 | fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis 17 | - name: Set up JDK 17 18 | uses: actions/setup-java@v3 19 | with: 20 | java-version: 17 21 | distribution: 'zulu' # Alternative distribution options are available. 22 | - name: Cache SonarCloud packages 23 | uses: actions/cache@v3 24 | with: 25 | path: ~/.sonar/cache 26 | key: ${{ runner.os }}-sonar 27 | restore-keys: ${{ runner.os }}-sonar 28 | - name: Cache Maven packages 29 | uses: actions/cache@v3 30 | with: 31 | path: ~/.m2 32 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} 33 | restore-keys: ${{ runner.os }}-m2 34 | - name: Build and analyze 35 | env: 36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any 37 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 38 | run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=krilop_PFP-PeopleForPeople -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/controller/RelationController.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.controller; 2 | 3 | import com.example.springhibernate.service.impl.RelationService; 4 | import lombok.AllArgsConstructor; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | @RestController 9 | @AllArgsConstructor 10 | @RequestMapping("api/v1/PFP") 11 | @CrossOrigin(origins = {"http://localhost:4200","http://localhost:3000"} ,allowCredentials = "true") 12 | public class RelationController { 13 | 14 | private final RelationService relationService; 15 | 16 | @PostMapping("/relations/new") 17 | public ResponseEntity createNewRelationType(@RequestParam("title") String title) 18 | { 19 | return relationService.createNewRelationType(title); 20 | } 21 | 22 | @PostMapping("/relations/{userId}/{anotherUserId}") 23 | public ResponseEntity createNewRelationBetweenUsers(@PathVariable("userId") Long userId, @PathVariable("anotherUserId") Long anotherId, @RequestParam("relationId") Long relationId) 24 | { 25 | return relationService.createNewRelation(userId, anotherId, relationId); 26 | } 27 | 28 | @GetMapping("/profile/{id}/relations") 29 | public ResponseEntity findAllRelationsForUser(@PathVariable("id")Long id) 30 | { 31 | return relationService.findAllRelationsForUser(id); 32 | } 33 | 34 | @GetMapping("/relations") 35 | public ResponseEntity findAllRelations() 36 | { 37 | return relationService.findAllRelations(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /JSP/src/main/webapp/friends.jsp: -------------------------------------------------------------------------------- 1 | <%@page import="org.example.data.Relation"%> 2 | <%@page import="org.example.crud.CRUDRelation"%> 3 | <%@page import="org.example.crud.CRUDAuthorization"%> 4 | <%@page import="org.example.data.Authorization"%> 5 | <%@page import="java.util.List"%> 6 | <%@page contentType="text/html" pageEncoding="UTF-8"%> 7 | 8 | 9 | 10 | PFP 11 | 12 | 13 | 14 | 15 | <% 16 | long userId = Long.parseLong(request.getParameter("id")); 17 | Authorization user = CRUDAuthorization.dbGetUserByID(userId); 18 | if (user != null) { 19 | %> 20 |

<%= "List of available contacts for user: " + user.getLogin() %>

21 | <% 22 | // Получение отношений из таблицы relation 23 | List relations = CRUDRelation.dbGetAllRelation(); 24 | boolean hasContacts = false; 25 | for (Relation rel : relations) { 26 | if ((rel.getUserId() == userId || rel.getFriendId() == userId) && rel.getRelationType() == 2) { 27 | hasContacts = true; 28 | %> 29 |

<%= (rel.getUserId() == userId) ? CRUDAuthorization.dbGetUserByID(rel.getFriendId()).getLogin() : CRUDAuthorization.dbGetUserByID(rel.getUserId()).getLogin() %>

30 | <% 31 | } 32 | } 33 | if (!hasContacts) { 34 | %> 35 |

Sorry, but for this user we don't have any additional information :(

36 | <% 37 | } 38 | } else { 39 | %> 40 |

User not found

41 | <% 42 | } 43 | %> 44 | 45 | 46 | -------------------------------------------------------------------------------- /frontend/src/components/App.js: -------------------------------------------------------------------------------- 1 | import logo from '../logo.svg'; 2 | import './App.css'; 3 | import AuthorizationComponent from "./authorization/authorization"; 4 | import {BrowserRouter, HashRouter, Route, Router, Routes} from "react-router-dom"; 5 | import React from "react"; 6 | import MainPageComponent from "./main-page/main-page"; 7 | import UserListComponent from "./user-list/user-list"; 8 | import RegistrationComponent from "./registration/registration"; 9 | import ProfileComponent from "./profile/profile"; 10 | import PostUserInfoComponent from "./post-user-info/post-user-info"; 11 | import InterestsComponent from "./interests/interests"; 12 | import ChangeUserInfoComponent from "./change-user-info/change-user-info"; 13 | 14 | function App() { 15 | return ( 16 | 17 |
18 | 19 | } /> 20 | } /> 21 | } /> 22 | } /> 23 | } /> 24 | } /> 25 | } /> 26 | } /> 27 | 28 |
29 |
30 | ); 31 | } 32 | 33 | export default App; 34 | -------------------------------------------------------------------------------- /frontend/src/components/user-list/user-list.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import UserInfoForList from '../user-info-for-list/user-info-for-list'; 3 | import HeaderComponent from '../header/header'; 4 | import UserService from '../../services/userService'; 5 | 6 | function UserListComponent() { 7 | const [userList, setUserList] = useState([]); 8 | const [id, setId] = useState(''); 9 | 10 | useEffect(() => { 11 | async function fetchData() { 12 | await loadUsers(); 13 | setId(localStorage.getItem('id')); 14 | } 15 | fetchData(); 16 | }, []); 17 | 18 | const loadUsers = async () => { 19 | try { 20 | const response = await UserService.getUsers(); 21 | setUserList(response.data); 22 | } catch (error) { 23 | console.error('Error loading users:', error); 24 | } 25 | }; 26 | 27 | return ( 28 |
29 | 30 | {userList && userList.length ? ( 31 |
32 | {userList.map(user => ( 33 | 34 | {user.id !== +id && } 35 | 36 | ))} 37 |
38 | ) : ( 39 |
40 |

No users found.

41 |
42 | )} 43 |
44 | ); 45 | } 46 | 47 | export default UserListComponent; 48 | -------------------------------------------------------------------------------- /frontend/src/components/interest-profile/interest-profile.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { useParams } from 'react-router-dom'; // Подключаем хук useParams для получения параметров маршрута 3 | import InterestsService from '../../services/interestService'; // Подключаем сервис для работы с интересами 4 | 5 | function InterestProfileComponent() { 6 | const [interests, setInterests] = useState([]); // Состояние для списка интересов 7 | const { id } = useParams(); // Получаем параметр id из маршрута 8 | 9 | useEffect(() => { 10 | getInterests(); // Получаем интересы при загрузке компонента 11 | }, [id]); // Перезагружаем компонент при изменении id 12 | 13 | // Функция для получения интересов пользователя 14 | const getInterests = async () => { 15 | try { 16 | const interestsData = await InterestsService.getInterestsOfUser(id); 17 | setInterests(interestsData || []); 18 | } catch (error) { 19 | console.error('Error fetching interests:', error); 20 | } 21 | }; 22 | 23 | return ( 24 |
25 |

Интересы пользователя

26 |
27 | {interests.map(interest => ( 28 |
29 | Interest 30 |

{interest.titleOfType}

31 |
32 | ))} 33 |
34 |
35 | ); 36 | } 37 | 38 | export default InterestProfileComponent; 39 | -------------------------------------------------------------------------------- /AngularFront/src/components/post-user-info/post-user-info.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Output, EventEmitter } from '@angular/core'; 2 | import {UserService} from "../../services/user-info/user.service"; 3 | import {FormsModule} from "@angular/forms"; 4 | import {CommonModule, NgIf} from "@angular/common"; 5 | import {Router} from "@angular/router"; 6 | 7 | @Component({ 8 | selector: 'app-post-user-info', 9 | standalone: true, 10 | imports: [ 11 | FormsModule, 12 | NgIf 13 | ], 14 | templateUrl: './post-user-info.component.html', 15 | styleUrl: './post-user-info.component.css' 16 | }) 17 | export class PostUserInfoComponent { 18 | 19 | user: any = { 20 | id:'', 21 | name: '', 22 | lastName: '', 23 | description: '', 24 | dateOfBirth: null, 25 | gender: '', 26 | media: '' 27 | }; 28 | 29 | constructor(private userService:UserService, private router:Router) { 30 | } 31 | onSubmit() { 32 | if (this.user.gender === 'male') { 33 | this.user.gender = true; 34 | } else { 35 | this.user.gender = false; 36 | } 37 | this.user.id = localStorage.getItem('id'); 38 | const dateObject = new Date(this.user.dateOfBirth); 39 | // Форматирование даты в нужный формат 40 | this.user.dateOfBirth = dateObject.toISOString().slice(0, 10); 41 | this.userService.saveUser(this.user).subscribe( 42 | (response) => { 43 | console.log('User saved successfully:', response); 44 | this.router.navigateByUrl(`/profile/${localStorage.getItem('id')}`); 45 | }, 46 | (error) => { 47 | console.error('Error saving user:', error); 48 | }); 49 | } 50 | previewImage() { 51 | this.user.media = this.user.imageLink; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /JDBC/src/main/java/org/example/Menu.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.example.crud.CRUDAuthorization; 6 | import org.example.crud.CRUDContact; 7 | import org.example.crud.CRUDRelation; 8 | 9 | import java.io.BufferedReader; 10 | import java.io.IOException; 11 | import java.io.InputStreamReader; 12 | import java.sql.SQLException; 13 | public class Menu { 14 | 15 | private Menu() 16 | { 17 | throw new IllegalStateException("Utility class"); 18 | } 19 | private static final Logger logger = LogManager.getLogger(Menu.class); 20 | static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 21 | public static void menu() throws IOException, SQLException 22 | { 23 | String caseTable; 24 | do { 25 | logger.info("\n\t\t\t--------- SELECT TABLE --------" + 26 | "\n\t1 - Authorization" + 27 | "\n\t2 - Contact" + 28 | "\n\t3 - Relation" + 29 | "\n\tAnother - cancel operation" + 30 | "\n\tEnter num:\n"); 31 | 32 | caseTable = br.readLine(); 33 | switch (caseTable) { 34 | case "1" -> 35 | CRUDAuthorization.crudAuthorization(); 36 | case "2" -> 37 | CRUDContact.crudContact(); 38 | case "3" -> 39 | CRUDRelation.crudRelation(); 40 | default -> { 41 | logger.info("Exit"); 42 | return; 43 | } 44 | 45 | } 46 | } while (true); 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /AngularFront/src/components/change-user-info/change-user-info.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 |
7 |
8 | 9 | 10 |
11 |
12 | 13 | 14 |
15 |
16 | 17 | 18 |
19 |
20 | 21 | 25 |
26 |
27 | 28 | 29 |
30 |
31 | 32 |
33 |
34 | Preview 35 |
36 | 37 |
38 |
39 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/service/impl/ContactService.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.service.impl; 2 | 3 | import com.example.springhibernate.model.Contact; 4 | import com.example.springhibernate.repository.ContactRepository; 5 | import com.example.springhibernate.repository.UserDataRepository; 6 | import com.example.springhibernate.service.ContService; 7 | import lombok.AllArgsConstructor; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.http.ResponseEntity; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.util.List; 13 | import java.util.Optional; 14 | 15 | @AllArgsConstructor 16 | @Service 17 | public class ContactService implements ContService { 18 | 19 | ContactRepository contactRepository; 20 | UserDataRepository userDataRepository; 21 | 22 | public ResponseEntity> findAllContactsById(Long id) 23 | { 24 | return new ResponseEntity<>(contactRepository.findContactsByUserDataId(id),HttpStatus.OK); 25 | } 26 | 27 | 28 | public ResponseEntity createContactForUser(Contact contact) { 29 | Contact savedContact = contactRepository.save(contact); 30 | return ResponseEntity.ok(savedContact); 31 | } 32 | 33 | public ResponseEntity removeContactForUser(Contact contact) { 34 | contactRepository.delete(contact); 35 | return ResponseEntity.ok("Successfully deleted"); 36 | } 37 | 38 | public Optional findContact(Long id) 39 | { 40 | return contactRepository.findById(id); 41 | } 42 | 43 | public ResponseEntity removeContactById(Long id) 44 | { 45 | contactRepository.deleteById(id); 46 | return new ResponseEntity<>(HttpStatus.OK); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /AngularFront/src/components/post-user-info/post-user-info.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 |
7 |
8 | 9 | 10 |
11 |
12 | 13 | 14 |
15 |
16 | 17 | 18 |
19 |
20 | 21 | 26 |
27 |
28 | 29 | 30 |
31 |
32 | 33 |
34 |
35 | Preview 36 |
37 | 38 |
39 |
40 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/controller/AuthController.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.controller; 2 | 3 | import com.example.springhibernate.DTO.JwtAuthenticationResponse; 4 | import com.example.springhibernate.DTO.SignInRequest; 5 | import com.example.springhibernate.DTO.SignUpRequest; 6 | import com.example.springhibernate.service.impl.AuthenticationService; 7 | import io.swagger.v3.oas.annotations.Operation; 8 | import io.swagger.v3.oas.annotations.tags.Tag; 9 | import jakarta.validation.Valid; 10 | import lombok.RequiredArgsConstructor; 11 | import org.apache.logging.log4j.LogManager; 12 | import org.apache.logging.log4j.Logger; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | @RestController 16 | @RequestMapping("/auth") 17 | @RequiredArgsConstructor 18 | @Tag(name = "Аутентификация") 19 | @CrossOrigin(origins = {"http://localhost:4200","http://localhost:3000"} ,allowCredentials = "true") 20 | public class AuthController { 21 | 22 | private final AuthenticationService authenticationService; 23 | private static final Logger logger = LogManager.getLogger(AuthController.class); 24 | @Operation(summary = "Регистрация пользователя") 25 | @PostMapping("/sign-up") 26 | public JwtAuthenticationResponse signUp(@RequestBody @Valid SignUpRequest request) { 27 | JwtAuthenticationResponse tmp = authenticationService.signUp(request); 28 | logger.info(tmp); 29 | return tmp; 30 | } 31 | 32 | @Operation(summary = "Авторизация пользователя") 33 | @PostMapping("/sign-in") 34 | public JwtAuthenticationResponse signIn(@RequestBody @Valid SignInRequest request) { 35 | JwtAuthenticationResponse tmp = authenticationService.signIn(request); 36 | logger.info(tmp); 37 | return tmp; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /AngularFront/src/components/registration/registration.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, ViewChild} from '@angular/core'; 2 | import {FormsModule, NgForm} from "@angular/forms"; 3 | import {AuthorizationService} from "../../services/authorization/authorization.service"; 4 | import {Router} from "@angular/router"; 5 | import {CommonModule} from "@angular/common"; 6 | 7 | 8 | @Component({ 9 | selector: 'app-registration', 10 | standalone: true, 11 | imports: [ 12 | FormsModule, 13 | CommonModule 14 | ], 15 | templateUrl: './registration.component.html', 16 | styleUrl: './registration.component.css' 17 | }) 18 | export class RegistrationComponent { 19 | @ViewChild('registrationForm') registrationForm!: NgForm; 20 | 21 | username: string = ''; 22 | email: string = ''; 23 | password: string = ''; 24 | emailErrorMessages: { [key: string]: string } = { 25 | 'required': 'Email is required.', 26 | 'email': 'Invalid email format.' 27 | }; 28 | 29 | constructor(private authorizationService: AuthorizationService, private router: Router) {} 30 | 31 | register() { 32 | this.authorizationService.register(this.username, this.email, this.password) 33 | .subscribe( 34 | response => { 35 | if (response.token) { 36 | localStorage.setItem('jwtToken', response.token); 37 | this.router.navigate(['/registration/part2']); 38 | } 39 | }, 40 | error => { 41 | console.error('Registration error', error); 42 | } 43 | ); 44 | } 45 | 46 | getEmailErrorMessage(): string { 47 | const emailControl = this.registrationForm.controls['email']; 48 | if (emailControl?.errors) { 49 | const errorKey = Object.keys(emailControl.errors)[0]; 50 | return this.emailErrorMessages[errorKey]; 51 | } 52 | return ''; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /AngularFront/src/services/authorization/authorization.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import {HttpClient} from "@angular/common/http"; 3 | import {Observable, tap} from "rxjs"; 4 | import { JwtHelperService } from '@auth0/angular-jwt'; 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class AuthorizationService { 9 | apiUrl = "http://localhost:8080/auth"; 10 | jwtHelper: JwtHelperService = new JwtHelperService(); // Создаем экземпляр сервиса для работы с JWT 11 | 12 | constructor(private http: HttpClient) { } 13 | 14 | login(username: string, password: string): Observable { 15 | return this.http.post(`${this.apiUrl}/sign-in`, { username, password }) 16 | .pipe( 17 | tap(response => { 18 | // Сохраняем токен в локальное хранилище 19 | localStorage.setItem('jwtToken', response.token); 20 | 21 | // Извлекаем идентификатор пользователя из токена 22 | const userId: string = this.getUserIdFromToken(response.token); 23 | localStorage.setItem('id', userId); 24 | }) 25 | ); 26 | } 27 | 28 | // Функция для извлечения идентификатора пользователя из токена JWT 29 | getUserIdFromToken(token: string): string { 30 | const decodedToken = this.jwtHelper.decodeToken(token); 31 | return decodedToken.id; 32 | } 33 | 34 | register(username: string, email: string, password: string): Observable { 35 | return this.http.post(`${this.apiUrl}/sign-up`, { username, email, password }) 36 | .pipe( 37 | tap(response => { 38 | // Сохраняем токен в локальное хранилище 39 | localStorage.setItem('jwtToken', response.token); 40 | // Извлекаем идентификатор пользователя из токена 41 | const userId: string = this.getUserIdFromToken(response.token); 42 | localStorage.setItem('id', userId); 43 | }) 44 | ); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | 7 | ### IntelliJ IDEA ### 8 | .idea/modules.xml 9 | .idea/jarRepositories.xml 10 | .idea/compiler.xml 11 | .idea/libraries/ 12 | *.iws 13 | *.iml 14 | *.ipr 15 | out/ 16 | !**/src/main/**/out/ 17 | !**/src/test/**/out/ 18 | 19 | ### Eclipse ### 20 | .apt_generated 21 | .classpath 22 | .factorypath 23 | .project 24 | .settings 25 | .springBeans 26 | .sts4-cache 27 | bin/ 28 | !**/src/main/**/bin/ 29 | !**/src/test/**/bin/ 30 | 31 | ### NetBeans ### 32 | /nbproject/private/ 33 | /nbbuild/ 34 | /dist/ 35 | /nbdist/ 36 | /.nb-gradle/ 37 | 38 | ### VS Code ### 39 | .vscode/ 40 | 41 | ### Mac OS ### 42 | .DS_Store 43 | 44 | # See http://help.github.com/ignore-files/ for more about ignoring files. 45 | 46 | # Compiled output 47 | /dist 48 | /tmp 49 | /out-tsc 50 | /bazel-out 51 | 52 | # Node 53 | /node_modules 54 | npm-debug.log 55 | yarn-error.log 56 | 57 | # IDEs and editors 58 | .idea/ 59 | .project 60 | .classpath 61 | .c9/ 62 | *.launch 63 | .settings/ 64 | *.sublime-workspace 65 | 66 | # Visual Studio Code 67 | .vscode/* 68 | !.vscode/settings.json 69 | !.vscode/tasks.json 70 | !.vscode/launch.json 71 | !.vscode/extensions.json 72 | .history/* 73 | 74 | # Miscellaneous 75 | /.angular/cache 76 | .sass-cache/ 77 | /connect.lock 78 | /coverage 79 | /libpeerconnection.log 80 | testem.log 81 | /typings 82 | 83 | # System files 84 | .DS_Store 85 | Thumbs.db 86 | 87 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 88 | 89 | # dependencies 90 | /node_modules 91 | /.pnp 92 | .pnp.js 93 | 94 | # testing 95 | /coverage 96 | 97 | # production 98 | /build 99 | 100 | # misc 101 | .DS_Store 102 | .env.local 103 | .env.development.local 104 | .env.test.local 105 | .env.production.local 106 | 107 | npm-debug.log* 108 | yarn-debug.log* 109 | yarn-error.log* 110 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/model/Pair.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.model; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | @Entity 11 | @Getter 12 | @Setter 13 | @Table(name = "pair") 14 | public class Pair { 15 | @Id 16 | @GeneratedValue(strategy = GenerationType.IDENTITY) 17 | private Long id; 18 | 19 | @ManyToOne(cascade = { 20 | CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE 21 | }) 22 | @JoinColumn(name = "user_id", referencedColumnName = "user_id",nullable = false) 23 | private UserData userId; 24 | 25 | @ManyToOne(cascade = { 26 | CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE 27 | }) 28 | @JoinColumn(name = "another_id", referencedColumnName = "user_id",nullable = false) 29 | private UserData anotherId; 30 | 31 | @Column(nullable = false) 32 | private Boolean direction; 33 | 34 | @ManyToMany(cascade = { 35 | CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE 36 | }) 37 | @JoinTable( 38 | name = "relation", 39 | joinColumns = @JoinColumn(name = "pair_id",referencedColumnName = "id"), 40 | inverseJoinColumns = @JoinColumn(name = "relation_type", referencedColumnName = "id")) 41 | private List relationTypes; 42 | 43 | public void addRelationTypes(RelationType relationType) { 44 | if(relationTypes == null||relationTypes.isEmpty()) 45 | relationTypes = new ArrayList<>(); 46 | relationTypes.add(relationType); 47 | relationType.getPairs().add(this); 48 | } 49 | 50 | public void removeRelationTypes(RelationType relationType) { 51 | if(relationTypes == null||relationTypes.isEmpty()) 52 | return; 53 | relationTypes.remove(relationType); 54 | relationType.getPairs().remove(this); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /AngularFront/src/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | import { AuthorizationComponent } from "../components/authorization/authorization.component"; 3 | import { MainPageComponent } from "../components/main-page/main-page.component"; 4 | import { RegistrationComponent } from "../components/registration/registration.component"; 5 | import {UserListComponent} from "../components/user-list/user-list.component"; 6 | import {ProfileComponent} from "../components/profile/profile.component"; 7 | import {PostUserInfoComponent} from "../components/post-user-info/post-user-info.component"; 8 | import {InterestsComponent} from "../components/interests/interests.component"; 9 | import {ChangeUserInfoComponent} from "../components/change-user-info/change-user-info.component"; 10 | 11 | export const routes: Routes = [ 12 | { 13 | path: '', 14 | pathMatch: 'full', 15 | redirectTo: '/main-page', 16 | }, 17 | { 18 | path: 'main-page', 19 | title: 'Main page', 20 | component: MainPageComponent 21 | }, 22 | { 23 | path: 'auth/sign-in', 24 | title: 'Authorization', 25 | component: AuthorizationComponent 26 | }, 27 | { 28 | path: 'auth/sign-up', 29 | title: 'Registration', 30 | component: RegistrationComponent 31 | }, 32 | { 33 | path: 'userlist', 34 | title: 'List of users', 35 | component: UserListComponent 36 | }, 37 | { 38 | path: 'profile/:id', 39 | title: 'Profile', 40 | component: ProfileComponent 41 | }, 42 | { 43 | path: 'registration/part2', 44 | title: 'Give some info about you', 45 | component: PostUserInfoComponent 46 | }, 47 | { 48 | path: 'change', 49 | title: 'Give some info about you', 50 | component: ChangeUserInfoComponent 51 | }, 52 | { 53 | path: 'interests', 54 | title: 'OMG!! U R SO INTERESTING!', 55 | component: InterestsComponent 56 | }, 57 | { 58 | path: '**', 59 | redirectTo: '/main-page', // Redirect to main page for any other path 60 | } 61 | ]; 62 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/controller/UserDataController.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.controller; 2 | 3 | import com.example.springhibernate.DTO.UserDTO; 4 | import com.example.springhibernate.model.UserData; 5 | import com.example.springhibernate.service.impl.UserDataService; 6 | import jakarta.validation.Valid; 7 | import lombok.AllArgsConstructor; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.http.ResponseEntity; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import java.util.List; 13 | import java.util.Optional; 14 | 15 | @RestController 16 | @AllArgsConstructor 17 | @RequestMapping("api/v1/PFP/") 18 | @CrossOrigin(origins = {"http://localhost:4200","http://localhost:3000"} ,allowCredentials = "true") 19 | public class UserDataController { 20 | 21 | private final UserDataService infoService; 22 | @PostMapping("profile/{id}/change") 23 | public ResponseEntity createUserData(@Valid @RequestBody UserDTO newUser, @PathVariable("id") Long id) { 24 | newUser.setId(id); 25 | ResponseEntity responseEntity = infoService.createUserDataById(newUser); 26 | return responseEntity; 27 | } 28 | 29 | @GetMapping("profile/{id}/info") 30 | public ResponseEntity findUserData(@PathVariable("id") Long id) { 31 | Optional userDataOptional = infoService.findUserDataById(id); 32 | return userDataOptional.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build()); 33 | } 34 | 35 | @GetMapping("userlist") 36 | public ResponseEntity> findAllUserData() 37 | { 38 | return new ResponseEntity<>(infoService.findAllUserData(), HttpStatus.OK); 39 | } 40 | 41 | @PutMapping("profile/{id}/change") 42 | public ResponseEntity changeUserData(@Valid @RequestBody UserDTO newUser,@PathVariable("id")Long id) 43 | { 44 | return infoService.changeUserData(newUser,id); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /JSP/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.example 8 | JSP 9 | 1.0-SNAPSHOT 10 | JSP 11 | war 12 | 13 | 14 | UTF-8 15 | 11 16 | 11 17 | 5.9.2 18 | 19 | 20 | 21 | 22 | org.example 23 | JDBC 24 | 1.0-SNAPSHOT 25 | 26 | 27 | jakarta.platform 28 | jakarta.jakartaee-web-api 29 | 9.1.0 30 | provided 31 | 32 | 33 | org.junit.jupiter 34 | junit-jupiter-api 35 | ${junit.version} 36 | test 37 | 38 | 39 | org.junit.jupiter 40 | junit-jupiter-engine 41 | ${junit.version} 42 | test 43 | 44 | 45 | org.postgresql 46 | postgresql 47 | 42.7.2 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-war-plugin 56 | 3.3.2 57 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/src/components/authorization/authorization.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import AuthorizationService from '../../services/authorizationService'; // Import the service 3 | import './authorization.css'; 4 | import { useNavigate } from 'react-router-dom'; 5 | 6 | function AuthorizationComponent() { 7 | const [username, setUsername] = useState(''); 8 | const [password, setPassword] = useState(''); 9 | const [errorMessage, setErrorMessage] = useState(''); 10 | const navigate = useNavigate(); 11 | 12 | const handleLogin = async (e) => { 13 | e.preventDefault(); // Prevent the default form submission 14 | 15 | try { 16 | const response = await AuthorizationService.login(username, password); // Await the login operation 17 | // If login is successful, navigate to '/userlist' 18 | navigate('/userlist'); 19 | } catch (error) { 20 | // Set error message if login fails 21 | setErrorMessage('Ошибка аутентификации. Проверьте введенные данные.'); 22 | console.error('Login error', error); 23 | } 24 | }; 25 | 26 | return ( 27 |
28 |

Authorization

29 |
{/* Bind the form submission to handleLogin */} 30 |
31 | 35 |
36 | 37 |
38 | 42 |
43 | 44 |
45 | {errorMessage &&

{errorMessage}

} 46 |
47 | ); 48 | } 49 | 50 | export default AuthorizationComponent; 51 | -------------------------------------------------------------------------------- /AngularFront/src/components/change-user-info/change-user-info.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input} from '@angular/core'; 2 | import {UserInfoForListComponent} from "../user-info-for-list/user-info-for-list.component"; 3 | import {UserInfoDTO} from "../../DTO/UserInfoDTO"; 4 | import {FormsModule} from "@angular/forms"; 5 | import {NgIf} from "@angular/common"; 6 | import {UserService} from "../../services/user-info/user.service"; 7 | import {Router} from "@angular/router"; 8 | 9 | @Component({ 10 | selector: 'app-change-user-info', 11 | standalone: true, 12 | imports: [ 13 | UserInfoForListComponent, 14 | FormsModule, 15 | NgIf 16 | ], 17 | templateUrl: './change-user-info.component.html', 18 | styleUrl: './change-user-info.component.css' 19 | }) 20 | export class ChangeUserInfoComponent { 21 | @Input() userInfo!: UserInfoDTO; 22 | 23 | user: any = { 24 | id:'', 25 | name: '', 26 | lastName: '', 27 | description: '', 28 | dateOfBirth: null, 29 | gender: '', 30 | media: '' 31 | }; 32 | 33 | constructor(private userService:UserService, private router:Router) { 34 | } 35 | onSubmit() { 36 | if (this.user.gender === 'male') { 37 | this.user.gender = true; 38 | } else { 39 | this.user.gender = false; 40 | } 41 | this.user.id = localStorage.getItem('id'); 42 | 43 | // Проверяем, была ли дата рождения изменена 44 | if (this.user.dateOfBirth != null) { 45 | const dateObject = new Date(this.user.dateOfBirth); 46 | // Форматирование даты в нужный формат 47 | this.user.dateOfBirth = dateObject.toISOString().slice(0, 10); 48 | } else { 49 | // Если дата рождения не была изменена или уже в правильном формате, оставляем ее без изменений 50 | this.user.dateOfBirth = null; 51 | } 52 | 53 | this.userService.changeUser(this.user).subscribe( 54 | (response) => { 55 | console.log('User saved successfully:', response); 56 | this.router.navigateByUrl(`/profile/${localStorage.getItem('id')}`); 57 | }, 58 | (error) => { 59 | console.error('Error saving user:', error); 60 | } 61 | ); 62 | } 63 | 64 | 65 | previewImage() { 66 | this.user.media = this.user.imageLink; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/controller/InterestController.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.controller; 2 | 3 | import com.example.springhibernate.DTO.InterestDTO; 4 | import com.example.springhibernate.model.Interest; 5 | import com.example.springhibernate.service.impl.InterestService; 6 | import jakarta.validation.Valid; 7 | import lombok.AllArgsConstructor; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import java.util.List; 12 | 13 | @RestController 14 | @AllArgsConstructor 15 | @RequestMapping("api/v1/PFP/interests") 16 | @CrossOrigin(origins = {"http://localhost:4200","http://localhost:3000"} ,allowCredentials = "true") 17 | public class InterestController { 18 | 19 | private final InterestService interestService; 20 | 21 | 22 | @GetMapping("/all") 23 | public ResponseEntity> findAllInterest() { 24 | return interestService.findAllInterests(); 25 | } 26 | 27 | @GetMapping("/{id}/new") 28 | public ResponseEntity> findAllInterestForUser(@PathVariable("id") Long id) { 29 | return interestService.findAllInterestsForUser(id); 30 | } 31 | 32 | @GetMapping("/{id}") 33 | public ResponseEntity> findAllInterestOfUser(@PathVariable("id") Long id) { 34 | return interestService.findAllInterestsOfUser(id); 35 | } 36 | 37 | @PostMapping("/{userId}/{interestId}") 38 | public ResponseEntity addUserInterest(@PathVariable("userId") Long userId, @PathVariable("interestId") Long interestId) { 39 | interestService.addUserInterest(userId, interestId); 40 | return ResponseEntity.ok().build(); 41 | } 42 | 43 | @DeleteMapping("/{userId}/{interestId}") 44 | public ResponseEntity deleteUserInterest(@PathVariable("userId") Long userId, @PathVariable("interestId") Long interestId) { 45 | interestService.removeUserInterest(userId, interestId); 46 | return ResponseEntity.ok().build(); 47 | } 48 | 49 | @PostMapping("/addNew") 50 | public ResponseEntity createNewInterest(@Valid @RequestBody InterestDTO newInterest) { 51 | return interestService.createNewInterest(newInterest); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /AngularFront/src/components/interests/interests.component.css: -------------------------------------------------------------------------------- 1 | .interests-container { 2 | text-align: center; 3 | margin-top: 50px; 4 | } 5 | 6 | .interests-container h1 { 7 | font-size: 24px; 8 | margin-bottom: 20px; 9 | } 10 | 11 | .interests { 12 | display: flex; 13 | flex-wrap: wrap; 14 | justify-content: center; 15 | } 16 | 17 | .interest { 18 | margin: 10px; 19 | width: 100px; 20 | height: 100px; 21 | border: 2px solid #ccc; 22 | border-radius: 50%; 23 | overflow: hidden; 24 | cursor: pointer; 25 | transition: border-color 0.3s, transform 0.3s; 26 | } 27 | 28 | .interest img { 29 | width: 100%; 30 | height: 100%; 31 | object-fit: cover; 32 | } 33 | 34 | .interest:hover { 35 | border-color: #007bff; 36 | transform: scale(1.1); 37 | } 38 | 39 | .add-interest { 40 | text-align: center; 41 | margin-top: 50px; 42 | } 43 | 44 | .add-interest h2 { 45 | font-size: 24px; 46 | margin-bottom: 20px; 47 | } 48 | 49 | .add-interest .form-group { 50 | margin-bottom: 20px; 51 | } 52 | 53 | .add-interest label { 54 | display: block; 55 | font-size: 16px; 56 | margin-bottom: 5px; 57 | } 58 | 59 | .add-interest input[type="text"] { 60 | width: 300px; 61 | padding: 10px; 62 | font-size: 16px; 63 | } 64 | 65 | .add-interest .interest { 66 | width: 100px; 67 | margin-top: 10px; 68 | display: block; 69 | } 70 | 71 | .add-interest button { 72 | padding: 10px 20px; 73 | font-size: 18px; 74 | background-color: #007bff; 75 | color: #fff; 76 | border: none; 77 | border-radius: 5px; 78 | cursor: pointer; 79 | transition: background-color 0.3s; 80 | } 81 | 82 | .add-interest button:disabled { 83 | background-color: #ccc; 84 | cursor: not-allowed; 85 | } 86 | 87 | .add-interest button:hover { 88 | background-color: #0056b3; 89 | } 90 | 91 | .ready-btn { 92 | margin-left: 66.666%; 93 | margin-top: 30px; 94 | padding: 10px 20px; 95 | font-size: 18px; 96 | background-color: #007bff; 97 | color: #fff; 98 | border: none; 99 | border-radius: 5px; 100 | cursor: pointer; 101 | transition: background-color 0.3s; 102 | } 103 | 104 | .ready-btn:hover { 105 | background-color: #0056b3; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PFP-PeopleForPeople 2 | Цель проекта - создание веб-приложения сайта для знакомств. 3 | 4 | [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=krilop_PFP-PeopleForPeople&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=krilop_PFP-PeopleForPeople) 5 | 6 | | Этап | Описание | План (часов) | Факт (часов) | 7 | |-----------------------------------|--------------------------------------------------------------------------------------------|--------------|--------------| 8 | | База данных | Придумать схему базы данных согласно теме проекта. Минимум 7 таблиц, обязательное наличие связи многие ко многим. Желательно использовать PostgreSQL. | 8 | 16 | 9 | | JDBC | Создание консольного приложения для выполнения CRUD-операций с использованием JDBC. | 12 | 8 | 10 | | JSP | Разработка клиентской части с использованием JSP. | 20 | 13 | 11 | | Backend на SpringBoot + Hibernate | Создание бэкэнда приложения с использованием SpringBoot и Hibernate. | 30 | 33 | 12 | | Angular - Frontend | Разработка фронтенда с использованием Angular. | 15 | 19 | 13 | | React - Frontend | Разработка фронтенда с использованием React. | 20 | 15 | 14 | ## Выполнение первого задания: База данных 15 | 16 | Для начала проекта была разработана схема базы данных, соответствующая теме проекта - сайту для знакомств. В результате работы над этим этапом было выполнено следующее: 17 | 18 | - Придумана схема базы данных, состоящая из 12 таблиц. 19 | - Обеспечена обязательная наличие связи многие ко многим между таблицами(user_data & interest_type). 20 | - Для реализации была выбрана PostgreSQL как основная СУБД. 21 | 22 | ![Схема базы данных](./dataAboutDB/DBForInternship.drawio.png) 23 | 24 | Для ознакомления с деталями схемы базы данных, вы можете просмотреть [скрипт](./dataAboutDB/schema). 25 | -------------------------------------------------------------------------------- /AngularFront/src/components/interests/interests.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {FormsModule} from "@angular/forms"; 3 | import {Router} from "@angular/router"; 4 | import {InterestsService} from "../../services/interests/interests.service"; 5 | import {InterestDTO} from "../../DTO/InterestDTO"; 6 | import {CommonModule} from "@angular/common"; 7 | 8 | @Component({ 9 | selector: 'app-interests', 10 | standalone: true, 11 | imports: [ 12 | FormsModule, CommonModule 13 | ], 14 | templateUrl: './interests.component.html', 15 | styleUrl: './interests.component.css' 16 | }) 17 | export class InterestsComponent implements OnInit { 18 | interests: InterestDTO[] = []; 19 | newInterest: InterestDTO = { id: 0, titleOfType: '', icon: '' }; 20 | showInterest: boolean = false; 21 | hoveredInterestName: string = ''; 22 | 23 | constructor(private interestService: InterestsService, private router: Router) { } 24 | 25 | ngOnInit(): void { 26 | this.getInterests(); 27 | } 28 | 29 | getInterests(): void { 30 | this.interestService.getInterestsForUser().subscribe(interests => { 31 | this.interests = interests; 32 | }); 33 | } 34 | 35 | addInterestToUser(interestId: number): void { 36 | // Добавить интерес к пользователю 37 | console.log('Adding interest with ID:', interestId); 38 | this.interestService.addInterestForUser(interestId).subscribe(response => { 39 | console.log('Interest added successfully:', response); 40 | }); 41 | } 42 | 43 | showInterestName(name: string): void { 44 | this.hoveredInterestName = name; 45 | this.showInterest = true; 46 | } 47 | 48 | hideInterestName(): void { 49 | this.showInterest = false; 50 | } 51 | 52 | addInterest(): void { 53 | console.log('Adding new interest:', this.newInterest); 54 | this.interestService.saveInterest(this.newInterest).subscribe(response => { 55 | console.log('New interest added successfully:', response); 56 | alert('New interest added successfully'); 57 | }); 58 | } 59 | removeInterest(interestId: number): void { 60 | this.interests = this.interests.filter(interest => interest.id !== interestId); 61 | } 62 | 63 | finish(): void { 64 | this.router.navigate([`/profile/${localStorage.getItem('id')}`]); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/model/UserData.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import jakarta.persistence.*; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | import java.time.LocalDate; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Entity 13 | @Getter 14 | @Setter 15 | @Table(name = "user_data") 16 | public class UserData { 17 | @Id 18 | @Column(name = "user_id") 19 | private Long id; 20 | 21 | @Column(nullable = false) 22 | private String name; 23 | 24 | @Column(name = "last_name") 25 | private String lastName; 26 | 27 | @Column 28 | private String description; 29 | 30 | @Column(name = "date_of_birth", nullable = false) 31 | private LocalDate dateOfBirth; 32 | 33 | @Column(nullable = false) 34 | private int gender; 35 | 36 | @Column 37 | @Transient 38 | private int age; 39 | 40 | @Column 41 | private String media; 42 | 43 | @JsonIgnore 44 | @ManyToMany(cascade = { 45 | CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE 46 | }) 47 | @JoinTable( 48 | name = "interest_user", 49 | joinColumns = @JoinColumn(name = "user_id"), 50 | inverseJoinColumns = @JoinColumn(name = "interest_id")) 51 | private List interests; 52 | 53 | @JsonIgnore 54 | @OneToMany(cascade = { 55 | CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE 56 | }) 57 | @JoinColumn(name = "user_id") 58 | private List contacts; 59 | 60 | @JsonIgnore 61 | @OneToOne(cascade = { 62 | CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE 63 | }) 64 | @PrimaryKeyJoinColumn 65 | private Authorization authorization; 66 | 67 | 68 | public void addInterest(Interest interest) { 69 | if(interests == null||interests.isEmpty()) 70 | interests = new ArrayList<>(); 71 | interests.add(interest); 72 | interest.getUserDataList().add(this); 73 | } 74 | 75 | // Метод для удаления интереса у пользователя (если необходимо) 76 | public void removeInterest(Interest interest) { 77 | if(interests == null||interests.isEmpty()) 78 | return; 79 | interests.remove(interest); 80 | interest.getUserDataList().remove(this); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /AngularFront/src/components/profile/profile.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {HeaderComponent} from "../header/header.component"; 3 | import {UserService} from "../../services/user-info/user.service"; 4 | import {ActivatedRoute, NavigationEnd, Router} from "@angular/router"; 5 | import {InterestProfileComponent} from "../interest-profile/interest-profile.component"; 6 | import {CommonModule} from "@angular/common"; 7 | import {filter, Subscription} from "rxjs"; 8 | 9 | @Component({ 10 | selector: 'app-profile', 11 | standalone: true, 12 | imports: [ 13 | HeaderComponent, 14 | InterestProfileComponent, 15 | CommonModule 16 | ], 17 | templateUrl: './profile.component.html', 18 | styleUrl: './profile.component.css' 19 | }) 20 | export class ProfileComponent { 21 | user: any; 22 | userIdFromRoute: string | null =''; 23 | userIdFromStorage: string | null =''; 24 | showEditButton: boolean = false; 25 | routerSubscription: Subscription | undefined; 26 | 27 | constructor( 28 | private route: ActivatedRoute, 29 | private router: Router, 30 | private userDataService: UserService 31 | ) { 32 | this.userIdFromStorage = localStorage.getItem('id'); 33 | this.routerSubscription = this.listenToRouteChanges(); 34 | } 35 | 36 | ngOnDestroy(): void { 37 | if (this.routerSubscription) { 38 | this.routerSubscription.unsubscribe(); 39 | } 40 | } 41 | 42 | private listenToRouteChanges(): Subscription { 43 | return this.router.events 44 | .pipe( 45 | 46 | filter(event => event instanceof NavigationEnd) 47 | ) 48 | .subscribe(() => { 49 | this.userIdFromRoute = this.route.snapshot.paramMap.get('id'); 50 | this.showEditButton = this.userIdFromRoute === this.userIdFromStorage; 51 | this.loadUser(); 52 | }); 53 | } 54 | 55 | private loadUser(): void { 56 | if (this.userIdFromRoute) { 57 | this.userDataService.getUser(this.userIdFromRoute).subscribe({ 58 | next: (data) => { 59 | this.user = data; 60 | }, 61 | error: (err) => { 62 | console.error('Error fetching user:', err); 63 | // Возможно, здесь стоит перенаправить пользователя на другую страницу или показать сообщение об ошибке 64 | } 65 | }); 66 | } 67 | } 68 | 69 | navigateToReg2(): void { 70 | this.router.navigateByUrl('change',this.user); 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/model/Authorization.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import jakarta.persistence.*; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import org.springframework.security.core.GrantedAuthority; 8 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 9 | import org.springframework.security.core.userdetails.UserDetails; 10 | 11 | import java.util.Collection; 12 | import java.util.List; 13 | 14 | @Entity 15 | @Table(name = "\"authorization\"") 16 | @Getter 17 | @Setter 18 | public class Authorization implements UserDetails { 19 | @Id 20 | @GeneratedValue(strategy = GenerationType.IDENTITY) 21 | @SequenceGenerator(name = "user_id_seq", sequenceName = "user_id_seq", allocationSize = 1) 22 | private Long id; 23 | 24 | @Column(unique = true, nullable = false) 25 | private String login; 26 | 27 | @JsonIgnore 28 | @Column(name = "hash_of_pass", nullable = false) 29 | private String hashOfPass; 30 | 31 | @Column(unique = true, nullable = false) 32 | private String email; 33 | 34 | @OneToOne(fetch = FetchType.LAZY, cascade = { 35 | CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE 36 | }) 37 | @JsonIgnore 38 | @PrimaryKeyJoinColumn(name = "user_data") 39 | private UserData userData; 40 | 41 | @Enumerated(EnumType.STRING) 42 | @Column(name = "role", nullable = false) 43 | private Role role; 44 | 45 | 46 | 47 | @Override 48 | public Collection getAuthorities() { 49 | return List.of(new SimpleGrantedAuthority(role.name())); 50 | } 51 | 52 | @Override 53 | public String getPassword() { 54 | return this.getHashOfPass(); 55 | } 56 | 57 | @Override 58 | public String getUsername() { 59 | return this.getLogin(); 60 | } 61 | 62 | @Override 63 | public boolean isAccountNonExpired() { 64 | return true; 65 | } 66 | 67 | @Override 68 | public boolean isAccountNonLocked() { 69 | return true; 70 | } 71 | 72 | @Override 73 | public boolean isCredentialsNonExpired() { 74 | return true; 75 | } 76 | 77 | @Override 78 | public boolean isEnabled() { 79 | return true; 80 | } 81 | 82 | // Constructors, getters, and setters omitted for brevity 83 | } 84 | -------------------------------------------------------------------------------- /JSP/src/main/webapp/sign_in.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.util.List" %> 2 | <%@ page import="org.example.data.Authorization" %> 3 | <%@ page import="org.example.crud.CRUDAuthorization" %> 4 | <%@ page import="com.google.common.hash.Hashing" %> 5 | <%@ page import="java.nio.charset.StandardCharsets" %> 6 | <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> 7 | 8 | 9 | 10 | 11 | PFP 12 | 13 | 14 | 15 | 16 | 17 | Регистрация 18 |
19 | 20 |

21 | 22 | 23 |

24 | 25 | 26 | 27 | <% 28 | // Проверяем, была ли отправлена форма 29 | if (request.getMethod().equals("POST")) { 30 | // Получаем параметры из запроса 31 | String emailOrLogin = request.getParameter("emailOrLogin"); 32 | String password = request.getParameter("password"); 33 | List authorizations = CRUDAuthorization.dbGetAllUsers(); 34 | for (Authorization auth : authorizations) { 35 | if (auth.getLogin().equals(emailOrLogin) || auth.getEmail().equals(emailOrLogin)) { 36 | if (Hashing.sha256().hashString(password, StandardCharsets.UTF_8).toString().equals(auth.getHashOfPass())) { 37 | // Аутентификация успешна, перенаправляем на главную страницу с id пользователя 38 | String contextPath = request.getContextPath(); 39 | response.sendRedirect(contextPath + "/index.jsp?id=" + auth.getId()); 40 | return; // Важно использовать return, чтобы прервать выполнение кода дальше 41 | } 42 | } 43 | } 44 | // Если код дошел сюда, аутентификация не удалась 45 | response.sendRedirect("${pageContext.request.contextPath}/login.jsp?error=1"); 46 | } 47 | %> 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /frontend/src/services/userService.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | const apiUrl = "http://localhost:8080/api/v1/PFP"; 4 | 5 | const UserService = { 6 | async getUsers(){ 7 | const token = localStorage.getItem('token'); 8 | try { 9 | return await axios.get(`${apiUrl}/userlist`, { 10 | headers: { 11 | 'Authorization': `Bearer ${token}`, 12 | 'Accept': 'application/json', 13 | 'Content-Type': 'application/json' 14 | } 15 | }); 16 | } catch (error) { 17 | throw error; // Здесь можно обработать ошибку 18 | } 19 | }, 20 | 21 | async getUser(id){ 22 | const token = localStorage.getItem('token'); 23 | try { 24 | return await axios.get(`${apiUrl}/profile/${id}/info`, { 25 | headers: { 26 | 'Authorization': `Bearer ${token}`, 27 | 'Accept': 'application/json', 28 | 'Content-Type': 'application/json' 29 | } 30 | }); 31 | } catch (error) { 32 | throw error; // Здесь можно обработать ошибку 33 | } 34 | }, 35 | 36 | async saveUser(user){ 37 | const token = localStorage.getItem('token'); 38 | const userId = localStorage.getItem('id'); 39 | try { 40 | return await axios.post(`${apiUrl}/profile/${userId}/change`, user, { 41 | headers: { 42 | 'Authorization': `Bearer ${token}`, 43 | 'Accept': 'application/json', 44 | 'Content-Type': 'application/json' 45 | } 46 | }); 47 | } catch (error) { 48 | throw error; // Здесь можно обработать ошибку 49 | } 50 | }, 51 | async changeUser(user){ 52 | const token = localStorage.getItem('token'); 53 | const userId = localStorage.getItem('id'); 54 | try { 55 | return await axios.put(`${apiUrl}/profile/${userId}/change`, user, { 56 | headers: { 57 | 'Authorization': `Bearer ${token}`, 58 | 'Accept': 'application/json', 59 | 'Content-Type': 'application/json' 60 | } 61 | }); 62 | } catch (error) { 63 | throw error; // Здесь можно обработать ошибку 64 | } 65 | } 66 | }; 67 | 68 | export default UserService; 69 | -------------------------------------------------------------------------------- /frontend/src/components/registration/registration.js: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import AuthorizationService from '../../services/authorizationService'; 3 | import './registration.css' 4 | import {useNavigate} from "react-router-dom"; 5 | 6 | function RegistrationComponent() { 7 | const [username, setUsername] = useState(''); 8 | const [email, setEmail] = useState(''); 9 | const [password, setPassword] = useState(''); 10 | const navigate = useNavigate(); 11 | 12 | const register = async (event) => { 13 | event.preventDefault(); 14 | try { 15 | const response = await AuthorizationService.register(username, email, password); 16 | navigate('/registration/part2'); 17 | } catch (error) { 18 | console.error('Registration error', error); 19 | } 20 | }; 21 | 22 | return ( 23 |
24 |

Register on PFP - People for People

25 |
26 |
27 | 31 |
32 |
33 | 40 |
41 |
42 | 46 |
47 | 50 |
51 |
52 | ); 53 | } 54 | 55 | export default RegistrationComponent; 56 | -------------------------------------------------------------------------------- /frontend/src/components/interests/interests.css: -------------------------------------------------------------------------------- 1 | .interests-container { 2 | text-align: center; 3 | margin-top: 50px; 4 | } 5 | 6 | .interests-container h1 { 7 | font-size: 24px; 8 | margin-bottom: 20px; 9 | } 10 | 11 | .interests { 12 | display: flex; 13 | flex-wrap: wrap; 14 | justify-content: center; 15 | } 16 | 17 | .interest { 18 | margin: 10px; 19 | width: 100px; 20 | height: 100px; 21 | border: 2px solid #ccc; 22 | border-radius: 50%; 23 | overflow: hidden; 24 | cursor: pointer; 25 | transition: border-color 0.3s, transform 0.3s; 26 | } 27 | 28 | .interest img { 29 | width: 100%; 30 | height: 100%; 31 | object-fit: cover; 32 | } 33 | 34 | .interest:hover { 35 | border-color: #007bff; 36 | transform: scale(1.1); 37 | } 38 | 39 | .add-interest { 40 | text-align: center; 41 | margin-top: 50px; 42 | } 43 | 44 | .add-interest h2 { 45 | font-size: 24px; 46 | margin-bottom: 20px; 47 | } 48 | 49 | .add-interest .form-group { 50 | margin-bottom: 20px; 51 | } 52 | 53 | .add-interest label { 54 | display: block; 55 | font-size: 16px; 56 | margin-bottom: 5px; 57 | } 58 | 59 | .add-interest input[type="text"] { 60 | width: 300px; 61 | padding: 10px; 62 | font-size: 16px; 63 | } 64 | 65 | .add-interest .interest { 66 | width: 100px; 67 | margin-top: 10px; 68 | display: block; 69 | } 70 | 71 | .add-interest button { 72 | padding: 10px 20px; 73 | font-size: 18px; 74 | background-color: #007bff; 75 | color: #fff; 76 | border: none; 77 | border-radius: 5px; 78 | cursor: pointer; 79 | transition: background-color 0.3s; 80 | } 81 | 82 | .add-interest button:disabled { 83 | background-color: #ccc; 84 | cursor: not-allowed; 85 | } 86 | 87 | .add-interest button:hover { 88 | background-color: #0056b3; 89 | } 90 | 91 | .ready-btn { 92 | margin-left: 66.666%; 93 | margin-top: 30px; 94 | padding: 10px 20px; 95 | font-size: 18px; 96 | width: 100px; 97 | background-color: #007bff; 98 | color: #fff; 99 | border: none; 100 | border-radius: 5px; 101 | cursor: pointer; 102 | transition: background-color 0.3s; 103 | } 104 | 105 | .ready-btn:hover { 106 | background-color: #0056b3; 107 | } 108 | 109 | .form-table { 110 | display: flex; 111 | flex-direction: column; 112 | margin: 0 auto; /* Установите автоматичесные отступы по бокам */ 113 | } 114 | -------------------------------------------------------------------------------- /frontend/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | PFP-PeopleForPeople 9 | 1.0-SNAPSHOT 10 | pom 11 | 12 | JDBC 13 | JSP 14 | SpringHibernate 15 | 16 | 17 | 18 | 17 19 | 17 20 | UTF-8 21 | krilop_PFP-PeopleForPeople 22 | krilop 23 | https://sonarcloud.io 24 | 25 | 26 | 27 | 28 | org.postgresql 29 | postgresql 30 | 42.7.2 31 | 32 | 33 | org.apache.logging.log4j 34 | log4j-api 35 | 2.23.0 36 | 37 | 38 | org.apache.logging.log4j 39 | log4j-core 40 | 2.23.0 41 | 42 | 43 | org.junit.jupiter 44 | junit-jupiter 45 | 5.9.1 46 | test 47 | 48 | 49 | 50 | 51 | central 52 | https://repo.maven.apache.org/maven2 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-compiler-plugin 61 | 3.8.1 62 | 63 | 1.8 64 | 1.8 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /JSP/src/main/webapp/registration.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.util.List" %> 2 | <%@ page import="org.example.data.Authorization" %> 3 | <%@ page import="org.example.crud.CRUDAuthorization" %> 4 | <%@ page import="com.google.common.hash.Hashing" %> 5 | <%@ page import="java.nio.charset.StandardCharsets" %> 6 | <%@ page import="java.sql.SQLException" %> 7 | <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> 8 | 9 | 10 | 11 | 12 | PFP 13 | 14 | 15 | 16 | 17 | <% 18 | if(request.getParameter("id")!=null) 19 | { 20 | response.sendRedirect("/index.jsp?id="+request.getParameter("id")); 21 | } 22 | %> 23 | Авторизация 24 |
25 | 26 |

27 | 28 | 29 | 30 |

31 | 32 | 33 |

34 | 35 | 36 | 37 | <% 38 | // Получаем параметры из запроса 39 | String email = request.getParameter("email"); 40 | String login = request.getParameter("login"); 41 | String password = request.getParameter("password"); 42 | List authorizations = CRUDAuthorization.dbGetAllUsers(); 43 | int source = 1; 44 | for (Authorization auth:authorizations) { 45 | if(source == 1 && (auth.getLogin().equals(login) || auth.getEmail().equals(email))) 46 | { 47 | source = 0; 48 | out.println("Registration failed!"); 49 | } 50 | } 51 | if(source==1&&email!=null&&login!=null&&password!=null) 52 | { 53 | try { 54 | CRUDAuthorization.createUser(login, password, email); 55 | } catch (SQLException e) { 56 | throw new RuntimeException(e); 57 | } 58 | out.println("Authentication successful!"); 59 | Authorization auth = CRUDAuthorization.dbGetUserByName(login); 60 | String contextPath = request.getContextPath(); 61 | response.sendRedirect(contextPath + "/index.jsp?id=" + auth.getId()); 62 | } 63 | %> 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /JDBC/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | JDBC 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 17 14 | 17 15 | UTF-8 16 | krilop_PFP-PeopleForPeople 17 | krilop 18 | https://sonarcloud.io 19 | 20 | 21 | 22 | 23 | org.postgresql 24 | postgresql 25 | 42.7.2 26 | 27 | 28 | org.apache.logging.log4j 29 | log4j-api 30 | 2.23.0 31 | 32 | 33 | org.apache.logging.log4j 34 | log4j-core 35 | 2.23.0 36 | 37 | 38 | org.junit.jupiter 39 | junit-jupiter 40 | 5.9.1 41 | test 42 | 43 | 44 | org.projectlombok 45 | lombok 46 | RELEASE 47 | provided 48 | 49 | 50 | com.google.guava 51 | guava 52 | 32.1.3-jre 53 | 54 | 55 | 56 | 57 | 58 | 59 | central 60 | https://repo.maven.apache.org/maven2 61 | 62 | 63 | 64 | 65 | 66 | 67 | org.apache.maven.plugins 68 | maven-compiler-plugin 69 | 3.8.1 70 | 71 | 14 72 | 14 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/service/impl/UserService.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.service.impl; 2 | 3 | import com.example.springhibernate.model.Authorization; 4 | import com.example.springhibernate.model.Role; 5 | import com.example.springhibernate.repository.UserRepository; 6 | import lombok.RequiredArgsConstructor; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.security.core.userdetails.UserDetailsService; 9 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 10 | import org.springframework.stereotype.Service; 11 | 12 | @Service 13 | @RequiredArgsConstructor 14 | public class UserService { 15 | private final UserRepository repository; 16 | 17 | /** 18 | * Сохранение пользователя 19 | * 20 | * @return сохраненный пользователь 21 | */ 22 | public Authorization save(Authorization user) { 23 | return repository.save(user); 24 | } 25 | 26 | 27 | /** 28 | * Создание пользователя 29 | * 30 | * @return созданный пользователь 31 | */ 32 | public Authorization create(Authorization user) { 33 | if (repository.existsByLogin(user.getUsername())) { 34 | // Заменить на свои исключения 35 | throw new RuntimeException("Пользователь с таким именем уже существует"); 36 | } 37 | 38 | if (repository.existsByEmail(user.getEmail())) { 39 | throw new RuntimeException("Пользователь с таким email уже существует"); 40 | } 41 | 42 | return save(user); 43 | } 44 | 45 | /** 46 | * Получение пользователя по имени пользователя 47 | * 48 | * @return пользователь 49 | */ 50 | public Authorization getByUsername(String username) { 51 | return repository.findByLogin(username) 52 | .orElseThrow(() -> new UsernameNotFoundException("Пользователь не найден")); 53 | } 54 | 55 | /** 56 | * Получение пользователя по имени пользователя 57 | *

58 | * Нужен для Spring Security 59 | * 60 | * @return пользователь 61 | */ 62 | public UserDetailsService userDetailsService() { 63 | return this::getByUsername; 64 | } 65 | 66 | /** 67 | * Получение текущего пользователя 68 | * 69 | * @return текущий пользователь 70 | */ 71 | public Authorization getCurrentUser() { 72 | // Получение имени пользователя из контекста Spring Security 73 | var username = SecurityContextHolder.getContext().getAuthentication().getName(); 74 | return getByUsername(username); 75 | } 76 | 77 | 78 | /** 79 | * Выдача прав администратора текущему пользователю 80 | *

81 | * Нужен для демонстрации 82 | */ 83 | @Deprecated 84 | public void getAdmin() { 85 | var user = getCurrentUser(); 86 | user.setRole(Role.ADMIN_ROLE); 87 | save(user); 88 | } 89 | } -------------------------------------------------------------------------------- /JSP/src/main/webapp/profile.jsp: -------------------------------------------------------------------------------- 1 | <%@page import="org.example.crud.CRUDContact" %> 2 | <%@page import="org.example.data.Contact" %> 3 | <%@page import="org.example.crud.CRUDAuthorization" %> 4 | <%@page import="org.example.data.Authorization" %> 5 | <%@page import="java.util.List" %> 6 | <%@ page import="org.example.data.ContactType" %> 7 | <%@ page import="org.example.DBFunctions" %> 8 | <%@ page import="java.sql.Connection" %> 9 | <%@ page import="java.sql.PreparedStatement" %> 10 | <%@ page import="java.sql.SQLException" %> 11 | <%@ page import="java.sql.ResultSet" %> 12 | <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> 13 | 14 | 15 | 16 | 17 | PFP 18 | 19 | 20 | 21 | 22 | 23 | <% 24 | Authorization user = CRUDAuthorization.dbGetUserByID(Long.parseLong(request.getParameter("check"))); 25 | %> 26 |

<%= "List of available contact for user:"+user.getLogin()%>

27 | <% 28 | List contacts = CRUDContact.dbGetAllContacts(); 29 | int cnt=0; 30 | for (Contact co: contacts) { 31 | if(user.getId()==co.getUserId()){ 32 | cnt++; 33 | String info=null; 34 | DBFunctions db = new DBFunctions(); 35 | Connection conn = null; 36 | ResultSet rs = null; 37 | PreparedStatement ps = null; 38 | try { 39 | conn = db.connectToDB("PFP", "krimlad", "krilop"); 40 | ps = conn.prepareStatement("SELECT contact_title FROM contact_type WHERE id = ?"); 41 | ps.setLong(1, co.getContactType()); 42 | rs = ps.executeQuery(); 43 | while (rs.next()) { 44 | info= rs.getString("contact_title"); 45 | } 46 | } catch (SQLException e) { 47 | throw new IllegalStateException(e); 48 | } finally { 49 | if (ps != null) { 50 | try { 51 | ps.close(); 52 | } catch (SQLException e) { 53 | } 54 | } 55 | if (rs != null) { 56 | try { 57 | rs.close(); 58 | } catch (SQLException e) { 59 | } 60 | } 61 | if (conn != null) { 62 | try { 63 | conn.close(); 64 | } catch (SQLException e) { 65 | } 66 | 67 | } 68 | } 69 | %> 70 | 74 | <% }} 75 | if(cnt==0){%> 76 |

Sorry, but for this user we don't have any additional information :(

77 | <%}%> 78 | 79 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/controller/ContactController.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.controller; 2 | 3 | import com.example.springhibernate.DTO.ContactDTO; 4 | import com.example.springhibernate.model.Contact; 5 | import com.example.springhibernate.model.ContactType; 6 | import com.example.springhibernate.model.UserData; 7 | import com.example.springhibernate.service.impl.ContactService; 8 | import com.example.springhibernate.service.impl.UserDataService; 9 | import jakarta.validation.Valid; 10 | import lombok.AllArgsConstructor; 11 | import org.springframework.http.HttpStatus; 12 | import org.springframework.http.ResponseEntity; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import java.util.Optional; 16 | @RestController 17 | @AllArgsConstructor 18 | @RequestMapping("api/v1/PFP/") 19 | @CrossOrigin(origins = {"http://localhost:4200","http://localhost:3000"} ,allowCredentials = "true") 20 | public class ContactController { 21 | 22 | private final UserDataService userDataService; 23 | private final ContactService contactService; 24 | 25 | @GetMapping("/profile/{id}/contacts") 26 | public ResponseEntity findAllContactsById(@PathVariable(name = "id") Long id) 27 | { 28 | return contactService.findAllContactsById(id); 29 | } 30 | 31 | @PostMapping("/contacts/{userId}") 32 | public ResponseEntity addContactToUser(@PathVariable("userId") Long userId, @Valid @RequestBody ContactDTO contactDTO) { 33 | Optional userOptional = userDataService.findUserDataById(userId); 34 | if (userOptional.isEmpty()) { 35 | return ResponseEntity.notFound().build(); // или другой подходящий ответ 36 | } 37 | UserData user = userOptional.get(); 38 | 39 | Contact contact = new Contact(); 40 | contact.setInfo(contactDTO.getInfo()); 41 | contact.setContactType(ContactType.valueOf(contactDTO.getContactType().toUpperCase())); 42 | contact.setUserData(user); 43 | 44 | try { 45 | contactService.createContactForUser(contact); 46 | user.getContacts().add(contact); // Добавляем контакт к списку контактов пользователя 47 | userDataService.updateUserData(user); // Сохраняем обновленные данные пользователя 48 | return ResponseEntity.ok().build(); // или другой подходящий ответ 49 | } catch (Exception e) { 50 | return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); // или другой подходящий ответ 51 | } 52 | } 53 | 54 | 55 | @DeleteMapping("/contacts/{contactId}") 56 | public ResponseEntity deleteContact(@PathVariable("contactId") Long contactId) { 57 | Optional contactOptional = contactService.findContact(contactId); 58 | if (contactOptional.isEmpty()) { 59 | return ResponseEntity.notFound().build(); 60 | } 61 | contactService.removeContactById(contactId); 62 | return ResponseEntity.noContent().build(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /frontend/src/components/profile/profile.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { useParams, useNavigate } from 'react-router-dom'; 3 | import Header from '../header/header'; 4 | //import InterestProfile from '../interest-profile/InterestProfileComponent'; 5 | import UserService from '../../services/userService'; 6 | import './profile.css'; 7 | import InterestProfileComponent from "../interest-profile/interest-profile"; 8 | function ProfileComponent() { 9 | const [user, setUser] = useState(null); 10 | const [showEditButton, setShowEditButton] = useState(false); 11 | const params = useParams(); 12 | const navigate = useNavigate(); 13 | let userIdFromRoute; 14 | useEffect(() => { 15 | const userIdFromStorage = localStorage.getItem('id'); 16 | userIdFromRoute = params.id; 17 | setShowEditButton(userIdFromRoute === userIdFromStorage); 18 | loadUser(userIdFromRoute); 19 | }, [params.id]); 20 | 21 | async function loadUser(userId) { 22 | if (userId) { 23 | try { 24 | const userData = await UserService.getUser(userId); 25 | console.log('User data received:', userData); // Log user data for debugging 26 | setUser(userData.data); // Set user data in state 27 | localStorage.setItem('gender', userData.data.gender) 28 | } catch (err) { 29 | console.error('Error fetching user:', err); 30 | // Handle error - display error message or redirect 31 | // For now, let's set user to null to indicate loading error 32 | setUser(null); 33 | } 34 | } 35 | } 36 | 37 | 38 | const navigateToEditProfile = () => { 39 | navigate(`/change`); // Navigate to edit profile page with current user ID 40 | }; 41 | 42 | if (!user) return
Error: Failed to load user data.
; // Display error message if user data is null or loading failed 43 | 44 | return ( 45 | <> 46 |
47 |
48 |
49 |
50 | Avatar 51 |
52 |
53 |

{user.name} {user.lastName}

54 |

{user.description}

55 |

Age: {user.age}

56 |

Gender: {user.gender ? 'male' : 'female'}

57 |
58 |
59 | {showEditButton && ( 60 |
61 | 62 |
63 | )} 64 |
65 | 66 | 67 | ); 68 | } 69 | 70 | export default ProfileComponent; -------------------------------------------------------------------------------- /AngularFront/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "AngularFront": { 7 | "projectType": "application", 8 | "schematics": {}, 9 | "root": "", 10 | "sourceRoot": "src", 11 | "prefix": "app", 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:application", 15 | "options": { 16 | "outputPath": "dist/angular-front", 17 | "index": "src/index.html", 18 | "browser": "src/main.ts", 19 | "polyfills": [ 20 | "zone.js" 21 | ], 22 | "tsConfig": "tsconfig.app.json", 23 | "assets": [ 24 | "src/favicon.ico", 25 | "src/assets" 26 | ], 27 | "styles": [ 28 | "src/styles.css" 29 | ], 30 | "scripts": [] 31 | }, 32 | "configurations": { 33 | "production": { 34 | "budgets": [ 35 | { 36 | "type": "initial", 37 | "maximumWarning": "500kb", 38 | "maximumError": "1mb" 39 | }, 40 | { 41 | "type": "anyComponentStyle", 42 | "maximumWarning": "2kb", 43 | "maximumError": "4kb" 44 | } 45 | ], 46 | "outputHashing": "all" 47 | }, 48 | "development": { 49 | "optimization": false, 50 | "extractLicenses": false, 51 | "sourceMap": true 52 | } 53 | }, 54 | "defaultConfiguration": "production" 55 | }, 56 | "serve": { 57 | "builder": "@angular-devkit/build-angular:dev-server", 58 | "configurations": { 59 | "production": { 60 | "buildTarget": "AngularFront:build:production" 61 | }, 62 | "development": { 63 | "buildTarget": "AngularFront:build:development" 64 | } 65 | }, 66 | "defaultConfiguration": "development" 67 | }, 68 | "extract-i18n": { 69 | "builder": "@angular-devkit/build-angular:extract-i18n", 70 | "options": { 71 | "buildTarget": "AngularFront:build" 72 | } 73 | }, 74 | "test": { 75 | "builder": "@angular-devkit/build-angular:karma", 76 | "options": { 77 | "polyfills": [ 78 | "zone.js", 79 | "zone.js/testing" 80 | ], 81 | "tsConfig": "tsconfig.spec.json", 82 | "assets": [ 83 | "src/favicon.ico", 84 | "src/assets" 85 | ], 86 | "styles": [ 87 | "src/styles.css" 88 | ], 89 | "scripts": [] 90 | } 91 | } 92 | } 93 | } 94 | }, 95 | "cli": { 96 | "analytics": "0f886e3e-3546-4efd-9362-5852afecf8a6" 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/JwtAuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate; 2 | 3 | import com.example.springhibernate.service.impl.JwtService; 4 | import com.example.springhibernate.service.impl.UserService; 5 | import jakarta.servlet.FilterChain; 6 | import jakarta.servlet.ServletException; 7 | import jakarta.servlet.http.HttpServletRequest; 8 | import jakarta.servlet.http.HttpServletResponse; 9 | import lombok.NonNull; 10 | import lombok.RequiredArgsConstructor; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 13 | import org.springframework.security.core.context.SecurityContext; 14 | import org.springframework.security.core.context.SecurityContextHolder; 15 | import org.springframework.security.core.userdetails.UserDetails; 16 | import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; 17 | import org.springframework.stereotype.Component; 18 | import org.springframework.web.filter.OncePerRequestFilter; 19 | 20 | import java.io.IOException; 21 | 22 | @Component 23 | @RequiredArgsConstructor 24 | public class JwtAuthenticationFilter extends OncePerRequestFilter { 25 | public static final String BEARER_PREFIX = "Bearer "; 26 | public static final String HEADER_NAME = "Authorization"; 27 | private final JwtService jwtService; 28 | private final UserService userService; 29 | 30 | @Override 31 | protected void doFilterInternal( 32 | @NonNull HttpServletRequest request, 33 | @NonNull HttpServletResponse response, 34 | @NonNull FilterChain filterChain 35 | ) throws ServletException, IOException { 36 | 37 | // Получаем токен из заголовка 38 | var authHeader = request.getHeader(HEADER_NAME); 39 | if (StringUtils.isEmpty(authHeader) || !StringUtils.startsWith(authHeader, BEARER_PREFIX)) { 40 | filterChain.doFilter(request, response); 41 | return; 42 | } 43 | 44 | // Обрезаем префикс и получаем имя пользователя из токена 45 | var jwt = authHeader.substring(BEARER_PREFIX.length()); 46 | var username = jwtService.extractUserName(jwt); 47 | 48 | if (StringUtils.isNotEmpty(username) && SecurityContextHolder.getContext().getAuthentication() == null) { 49 | UserDetails userDetails = userService 50 | .userDetailsService() 51 | .loadUserByUsername(username); 52 | 53 | // Если токен валиден, то аутентифицируем пользователя 54 | if (jwtService.isTokenValid(jwt, userDetails)) { 55 | SecurityContext context = SecurityContextHolder.createEmptyContext(); 56 | 57 | UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( 58 | userDetails, 59 | null, 60 | userDetails.getAuthorities() 61 | ); 62 | 63 | authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); 64 | context.setAuthentication(authToken); 65 | SecurityContextHolder.setContext(context); 66 | } 67 | } 68 | filterChain.doFilter(request, response); 69 | } 70 | } -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | np# Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 13 | 14 | The page will reload when you make changes.\ 15 | You may also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!** 35 | 36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. 39 | 40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /SpringHibernate/src/main/java/com/example/springhibernate/service/impl/AuthenticationService.java: -------------------------------------------------------------------------------- 1 | package com.example.springhibernate.service.impl; 2 | 3 | import com.example.springhibernate.DTO.JwtAuthenticationResponse; 4 | import com.example.springhibernate.DTO.SignInRequest; 5 | import com.example.springhibernate.DTO.SignUpRequest; 6 | import com.example.springhibernate.model.Authorization; 7 | import com.example.springhibernate.model.Role; 8 | import lombok.RequiredArgsConstructor; 9 | import org.apache.logging.log4j.LogManager; 10 | import org.apache.logging.log4j.Logger; 11 | import org.springframework.security.authentication.AuthenticationManager; 12 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 13 | import org.springframework.security.core.userdetails.UserDetails; 14 | import org.springframework.security.core.userdetails.UserDetailsService; 15 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 16 | import org.springframework.security.crypto.password.PasswordEncoder; 17 | import org.springframework.stereotype.Service; 18 | import org.springframework.transaction.annotation.Transactional; 19 | 20 | 21 | @Service 22 | @RequiredArgsConstructor 23 | public class AuthenticationService implements UserDetailsService { 24 | private final UserService userService; 25 | private final JwtService jwtService; 26 | private final PasswordEncoder passwordEncoder; 27 | private final AuthenticationManager authenticationManager; 28 | private static final Logger logger = LogManager.getLogger(AuthenticationService.class); 29 | /** 30 | * Регистрация пользователя 31 | * 32 | * @param request данные пользователя 33 | * @return токен 34 | */ 35 | public JwtAuthenticationResponse signUp(SignUpRequest request) { 36 | 37 | Authorization user = new Authorization(); 38 | user.setRole(Role.USER_ROLE); 39 | user.setEmail(request.getEmail()); 40 | user.setLogin(request.getUsername()); 41 | user.setHashOfPass(passwordEncoder.encode(request.getPassword())); 42 | userService.create(user); 43 | var jwt = jwtService.generateToken(user); 44 | return new JwtAuthenticationResponse(jwt); 45 | } 46 | 47 | /** 48 | * Аутентификация пользователя 49 | * 50 | * @param request данные пользователя 51 | * @return токен 52 | */ 53 | public JwtAuthenticationResponse signIn(SignInRequest request) { 54 | authenticationManager.authenticate(new UsernamePasswordAuthenticationToken( 55 | request.getUsername(), 56 | request.getPassword() 57 | )); 58 | logger.info("username:"+request.getUsername()+"pass:"+request.getPassword()); 59 | var user = userService 60 | .userDetailsService() 61 | .loadUserByUsername(request.getUsername()); 62 | 63 | var jwt = jwtService.generateToken(user); 64 | return new JwtAuthenticationResponse(jwt); 65 | } 66 | 67 | 68 | @Override 69 | @Transactional 70 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 71 | Authorization user = userService.getByUsername(username); 72 | return new org.springframework.security.core.userdetails.User( 73 | user.getUsername(), 74 | user.getPassword(), 75 | user.getAuthorities() 76 | ); 77 | } 78 | 79 | public void createNewUser(Authorization user) 80 | { 81 | user.setRole(Role.USER_ROLE); 82 | userService.create(user); 83 | 84 | } 85 | } 86 | 87 | -------------------------------------------------------------------------------- /frontend/src/services/interestService.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | const apiUrl = "http://localhost:8080/api/v1/PFP"; 4 | 5 | const InterestsService = { 6 | async getInterests() { 7 | const token = localStorage.getItem('token'); 8 | try { 9 | const response = await axios.get(`${apiUrl}/interests/all`, { 10 | headers: { 11 | 'Authorization': `Bearer ${token}`, 12 | 'Accept': 'application/json', 13 | 'Content-Type': 'application/json' 14 | } 15 | }); 16 | return response.data; 17 | } catch (error) { 18 | throw error; 19 | } 20 | }, 21 | async getInterestsForUser() { 22 | const token = localStorage.getItem('token'); 23 | const userId = localStorage.getItem('id'); 24 | try { 25 | const response = await axios.get(`${apiUrl}/interests/${userId}/new`, { 26 | headers: { 27 | 'Authorization': `Bearer ${token}`, 28 | 'Accept': 'application/json', 29 | 'Content-Type': 'application/json' 30 | } 31 | }); 32 | return response.data; 33 | } catch (error) { 34 | throw error; 35 | } 36 | }, 37 | async getInterestsOfUser(id) { 38 | const token = localStorage.getItem('token'); 39 | try { 40 | const response = await axios.get(`${apiUrl}/interests/${id}`, { 41 | headers: { 42 | 'Authorization': `Bearer ${token}`, 43 | 'Accept': 'application/json', 44 | 'Content-Type': 'application/json' 45 | } 46 | }); 47 | return response.data; 48 | } catch (error) { 49 | throw error; 50 | } 51 | }, 52 | async deleteInterestOfUser(id) { 53 | const token = localStorage.getItem('token'); 54 | const userId = localStorage.getItem('id'); 55 | try { 56 | const response = await axios.delete(`${apiUrl}/interests/${userId}/${id}`, { 57 | headers: { 58 | 'Authorization': `Bearer ${token}`, 59 | 'Accept': 'application/json', 60 | 'Content-Type': 'application/json' 61 | } 62 | }); 63 | return response.data; 64 | } catch (error) { 65 | throw error; 66 | } 67 | }, 68 | async saveInterest(interest) { 69 | const token = localStorage.getItem('token'); 70 | try { 71 | const response = await axios.post(`${apiUrl}/interests/addNew`, interest, { 72 | headers: { 73 | 'Authorization': `Bearer ${token}`, 74 | 'Accept': 'application/json', 75 | 'Content-Type': 'application/json' 76 | } 77 | }); 78 | return response.data; 79 | } catch (error) { 80 | throw error; 81 | } 82 | }, 83 | async addInterestForUser(id) { 84 | const token = localStorage.getItem('token'); 85 | const userId = localStorage.getItem('id'); 86 | try { 87 | const response = await axios.post(`${apiUrl}/interests/${userId}/${id}`, '', { 88 | headers: { 89 | 'Authorization': `Bearer ${token}`, 90 | 'Accept': 'application/json', 91 | 'Content-Type': 'application/json' 92 | } 93 | }); 94 | return response.data; 95 | } catch (error) { 96 | throw error; 97 | } 98 | } 99 | }; 100 | 101 | export default InterestsService; 102 | -------------------------------------------------------------------------------- /dataAboutDB/schema: -------------------------------------------------------------------------------- 1 | create table public."authorization" 2 | ( 3 | id bigint generated always as identity 4 | constraint pk_authorization_id 5 | primary key, 6 | email text not null, 7 | login text not null, 8 | hash_of_pass text not null 9 | ); 10 | 11 | alter table public."authorization" 12 | owner to postgres; 13 | 14 | create table public.relation_type 15 | ( 16 | id bigint generated always as identity 17 | constraint pk_relation_type_id 18 | primary key, 19 | relation_title text not null 20 | constraint unique_relation_title 21 | unique 22 | ); 23 | 24 | alter table public.relation_type 25 | owner to postgres; 26 | 27 | create table public.user_data 28 | ( 29 | name text not null, 30 | last_name text, 31 | description text, 32 | date_of_birth date not null, 33 | gender integer not null, 34 | user_id bigint not null 35 | constraint pk_user_data_user_id 36 | primary key 37 | constraint unique_user_id 38 | unique 39 | constraint authorization_id 40 | references public."authorization", 41 | media text 42 | ); 43 | 44 | alter table public.user_data 45 | owner to postgres; 46 | 47 | create table public.contact 48 | ( 49 | id bigint generated always as identity 50 | constraint pk_contact_id 51 | primary key, 52 | user_id bigint not null 53 | constraint authorization_id 54 | references public."authorization" 55 | constraint fk8d2k0kb9pa6l7jgv8sytibyuk 56 | references public.user_data, 57 | info text not null, 58 | contact_type contact_type_enum not null 59 | ); 60 | 61 | alter table public.contact 62 | owner to postgres; 63 | 64 | create table public.pair 65 | ( 66 | user_id bigint not null 67 | constraint fk_pair_user_id 68 | references public.user_data, 69 | another_id bigint not null 70 | constraint fk_pair_another_id 71 | references public.user_data, 72 | id bigint not null 73 | primary key, 74 | direction boolean not null, 75 | constraint pair_user_id_another_id_direction 76 | unique (user_id, another_id, direction) 77 | ); 78 | 79 | alter table public.pair 80 | owner to postgres; 81 | 82 | create table public.relation 83 | ( 84 | id bigint generated always as identity 85 | constraint pk_relation_id 86 | primary key, 87 | pair_id bigint not null 88 | constraint pair_id 89 | references public.pair, 90 | relation_type bigint not null 91 | constraint relation_type_id 92 | references public.relation_type, 93 | direction boolean not null 94 | ); 95 | 96 | alter table public.relation 97 | owner to postgres; 98 | 99 | create table public.interest 100 | ( 101 | id bigserial 102 | primary key, 103 | title_of_type text not null 104 | constraint uk_e6vdadct9528dgt16txehj49t 105 | unique, 106 | icon text not null 107 | ); 108 | 109 | alter table public.interest 110 | owner to krimlad; 111 | 112 | create table public.interest_user 113 | ( 114 | id bigint generated always as identity 115 | constraint pk_interest_type_user_id 116 | primary key, 117 | user_id bigint not null 118 | constraint authorization_id 119 | references public."authorization" 120 | constraint fkjg8qspgahfc6o0244jxbj30b1 121 | references public.user_data, 122 | interest_id bigint not null 123 | constraint fkn2pn4l4g6qphoe6coh7uwcuko 124 | references public.interest 125 | ); 126 | 127 | alter table public.interest_user 128 | owner to postgres; 129 | 130 | -------------------------------------------------------------------------------- /frontend/src/components/post-user-info/post-user-info.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import UserService from '../../services/userService'; 3 | import { useNavigate } from 'react-router-dom'; 4 | 5 | import './post-user-info.css'; 6 | 7 | function PostUserInfoComponent() { 8 | const [user, setUser] = useState({ 9 | id: 0, 10 | name: '', 11 | lastName: '', 12 | description: '', 13 | dateOfBirth: null, 14 | gender: '', 15 | media: '' 16 | }); 17 | const history = useNavigate(); 18 | 19 | const onSubmit = async (e) => { 20 | e.preventDefault(); // Prevent default form submission 21 | 22 | const newUser = { ...user }; 23 | 24 | newUser.gender = newUser.gender === 'male'; 25 | 26 | newUser.id = localStorage.getItem('id'); 27 | 28 | newUser.dateOfBirth = new Date(newUser.dateOfBirth).toISOString().slice(0, 10); 29 | 30 | try { 31 | const response = await UserService.saveUser(newUser); 32 | console.log('User saved successfully:', response); 33 | history(`/profile/${localStorage.getItem('id')}`); 34 | } catch (error) { 35 | console.error('Error saving user:', error); 36 | } 37 | }; 38 | const previewImage = () => { 39 | setUser({ ...user, media: user.imageLink }); 40 | }; 41 | 42 | return ( 43 |
44 |
45 |
46 | 47 | setUser({ ...user, name: e.target.value })} required /> 48 |
49 |
50 | 51 | setUser({ ...user, lastName: e.target.value })} required /> 52 |
53 |
54 | 55 | 56 |
57 |
58 | 59 | setUser({ ...user, dateOfBirth: e.target.value })} required /> 60 |
61 |
62 | 63 | 68 |
69 |
70 | 71 | setUser({ ...user, media: e.target.value })} required /> 72 |
73 |
74 | 75 |
76 |
77 | {user.media && Preview} 78 |
79 | 80 |
81 |
82 | ); 83 | } 84 | 85 | export default PostUserInfoComponent; 86 | --------------------------------------------------------------------------------