first commit

This commit is contained in:
Dhanraj
2024-09-22 10:21:52 +05:30
parent 9c6c3abc32
commit bd5119fc3c
697 changed files with 112184 additions and 10841 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -29,6 +29,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency> -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
@ -100,11 +106,11 @@
<version>1.12.75</version>
</dependency>
<dependency>
<!-- <dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
</dependency> -->
<dependency>
<groupId>org.springframework.boot</groupId>
@ -197,8 +203,13 @@
</annotationProcessorPaths>
<compilerArgs>
<compilerArg>
-Amapstruct.defaultComponentModel=spring
<arg>-Amapstruct.defaultComponentModel=spring</arg>
<arg>-Amapstruct.verbose=true</arg>
</compilerArg>
</compilerArgs>
</configuration>
</plugin>
@ -246,6 +257,9 @@
</configuration>
</plugin>
</plugins>
</build>

View File

@ -0,0 +1,74 @@
package net.shyshkin.study.fullstack.supportportal.backend.config;
import net.shyshkin.study.fullstack.supportportal.backend.domain.User;
import net.shyshkin.study.fullstack.supportportal.backend.repository.UserRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.util.UUID;
import static net.shyshkin.study.fullstack.supportportal.backend.constant.Authority.*;
@Configuration
public class DataInitializer {
@Bean
public CommandLineRunner init(UserRepository userRepository, PasswordEncoder passwordEncoder) {
return args -> {
System.out.println("Running DataInitializer...");
// Initialize users
createUserIfNotExists(userRepository, passwordEncoder, "admin", "adminpassword", "admin@example.com", "Admin", "User", "ROLE_ADMIN");
createUserIfNotExists(userRepository, passwordEncoder, "hr", "hrpassword", "hr@example.com", "HR", "User", "ROLE_HR");
createUserIfNotExists(userRepository, passwordEncoder, "manager", "managerpassword", "manager@example.com", "Manager", "User", "ROLE_MANAGER");
createUserIfNotExists(userRepository, passwordEncoder, "user", "userpassword", "user@example.com", "Regular", "User", "ROLE_USER");
createUserIfNotExists(userRepository, passwordEncoder, "superadmin", "superadminpassword", "superadmin@example.com", "Super", "Admin", "ROLE_SUPER_ADMIN");
};
}
private void createUserIfNotExists(UserRepository userRepository, PasswordEncoder passwordEncoder,
String username, String password, String email,
String firstName, String lastName, String role) {
if (userRepository.findByUsername(username).isEmpty()) {
String encodedPassword = passwordEncoder.encode(password);
User user = User.builder()
.email(email)
.firstName(firstName)
.lastName(lastName)
.username(username)
.password(encodedPassword)
.userId(UUID.randomUUID())
.isActive(true)
.isNotLocked(true)
.role(role)
.authorities(getAuthoritiesByRole(role))
.build();
userRepository.save(user);
System.out.println(role + " user created successfully.");
} else {
System.out.println(role + " user already exists.");
}
}
private String[] getAuthoritiesByRole(String role) {
switch (role) {
case "ROLE_ADMIN":
return ADMIN_AUTHORITIES;
case "ROLE_HR":
return HR_AUTHORITIES;
case "ROLE_MANAGER":
return MANAGER_AUTHORITIES;
case "ROLE_USER":
return USER_AUTHORITIES;
case "ROLE_SUPER_ADMIN":
return SUPER_ADMIN_AUTHORITIES;
default:
throw new IllegalArgumentException("Invalid role: " + role);
}
}
}

View File

@ -0,0 +1,19 @@
// package com.example.tamilnadureservoir.config;
package net.shyshkin.study.fullstack.supportportal.backend.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

View File

@ -14,4 +14,10 @@ public class FileConstant {
public static final String NOT_AN_IMAGE_FILE = " is not an image file. Please upload an image file";
public static final String TEMP_PROFILE_IMAGE_BASE_URL = "https://robohash.org/";
// public static final String PROFESSOR_IMAGE_PATH = "/professor/image/";
// public static final String PROFESSOR_FOLDER = System.getProperty("user.home") + "/supportportal/professor/";
// public static final String DEFAULT_PROFESSOR_IMAGE_URI_PATTERN = "/professor/%s/profile-image";
// public static final String PROFESSOR_IMAGE_FILENAME = "avatar.jpg";
}

View File

@ -0,0 +1,58 @@
package net.shyshkin.study.fullstack.supportportal.backend.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Event;
import net.shyshkin.study.fullstack.supportportal.backend.repository.EventRepository;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/api/events")
public class EventController {
@Autowired
private EventRepository eventRepository;
@GetMapping
public ResponseEntity<List<Event>> getAllEvents() {
List<Event> events = eventRepository.findAll();
return new ResponseEntity<>(events, HttpStatus.OK);
}
@GetMapping("/{id}")
public ResponseEntity<Event> getEventById(@PathVariable Long id) {
Optional<Event> event = eventRepository.findById(id);
return event.map(ResponseEntity::ok)
.orElseGet(() -> ResponseEntity.notFound().build());
}
@PostMapping
public ResponseEntity<Event> createEvent(@RequestBody Event event) {
Event savedEvent = eventRepository.save(event);
return new ResponseEntity<>(savedEvent, HttpStatus.CREATED);
}
@PutMapping("/{id}")
public ResponseEntity<Event> updateEvent(@PathVariable Long id, @RequestBody Event event) {
if (!eventRepository.existsById(id)) {
return ResponseEntity.notFound().build();
}
event.setId(id);
Event updatedEvent = eventRepository.save(event);
return new ResponseEntity<>(updatedEvent, HttpStatus.OK);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteEvent(@PathVariable Long id) {
if (!eventRepository.existsById(id)) {
return ResponseEntity.notFound().build();
}
eventRepository.deleteById(id);
return ResponseEntity.noContent().build();
}
}

View File

@ -0,0 +1,141 @@
package net.shyshkin.study.fullstack.supportportal.backend.controller;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Post;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Professor;
import net.shyshkin.study.fullstack.supportportal.backend.domain.dto.PostDto;
import net.shyshkin.study.fullstack.supportportal.backend.repository.PostRepository;
import net.shyshkin.study.fullstack.supportportal.backend.repository.ProfessorRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.amazonaws.services.secretsmanager.model.ResourceNotFoundException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/posts")
public class PostController {
@Autowired
private PostRepository postRepository;
// Get all posts where isPosted is true
@GetMapping("/posted")
public ResponseEntity<List<Post>> getAllPostedPosts() {
try {
List<Post> posts = postRepository.findAllByIsPostedTrue();
return ResponseEntity.ok(posts);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
// Get all unique tags with count
@GetMapping("/tags/count")
public ResponseEntity<Map<String, Long>> getTagsWithCount() {
try {
List<Object[]> tagCounts = postRepository.findTagsWithCount();
Map<String, Long> tagCountMap = new HashMap<>();
for (Object[] tagCount : tagCounts) {
tagCountMap.put((String) tagCount[0], (Long) tagCount[1]);
}
return ResponseEntity.ok(tagCountMap);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
// Get all posts associated with a specific tag where isPosted is true
@GetMapping("/tag/{tag}")
public ResponseEntity<List<Post>> getPostsByTag(@PathVariable String tag) {
try {
List<Post> posts = postRepository.findAllByTagAndIsPostedTrue(tag);
return ResponseEntity.ok(posts);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
// Get all posts
@GetMapping
public List<Post> getAllPosts() {
return postRepository.findAll();
}
// Get a single post by ID
@GetMapping("/{id}")
public ResponseEntity<Post> getPostById(@PathVariable Long id) {
return postRepository.findById(id)
.map(post -> ResponseEntity.ok(post))
.orElse(ResponseEntity.notFound().build());
}
@Autowired
private ProfessorRepository professorRepository;
@PostMapping
public ResponseEntity<?> createPost(@RequestBody PostDto postDto) {
Post post = new Post();
post.setTitle(postDto.getTitle());
post.setContent(postDto.getContent());
post.setPosted(postDto.isPosted());
// Fetch professors from IDs, filter out null IDs
List<Long> validProfessorIds = postDto.getProfessors().stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());
List<Professor> professors = professorRepository.findAllById(validProfessorIds);
post.setProfessors(professors);
// Set tags
post.setTags(postDto.getTags());
// Save the post
postRepository.save(post);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
@PutMapping("/{id}")
public ResponseEntity<?> updatePost(@PathVariable Long id, @RequestBody PostDto postDto) {
Post post = postRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Post not found"));
post.setTitle(postDto.getTitle());
post.setContent(postDto.getContent());
post.setPosted(postDto.isPosted());
// Fetch professors from IDs, filter out null IDs
List<Long> validProfessorIds = postDto.getProfessors().stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());
List<Professor> professors = professorRepository.findAllById(validProfessorIds);
post.setProfessors(professors);
// Set tags
post.setTags(postDto.getTags());
// Save the updated post
postRepository.save(post);
return ResponseEntity.ok().build();
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deletePost(@PathVariable Long id) {
return postRepository.findById(id)
.map(post -> {
postRepository.delete(post);
return ResponseEntity.noContent().<Void>build(); // Explicitly specify the type parameter
})
.orElse(ResponseEntity.notFound().build());
}
}

View File

@ -0,0 +1,36 @@
package net.shyshkin.study.fullstack.supportportal.backend.controller;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PostDTO
{
@NotNull
private String title;
@NotNull
private String content;
@NotEmpty(message = "At least one professor must be selected.")
private List<Long> professors;
private List<String> tags;
private boolean posted;
// Getters and setters
// ...
}

View File

@ -0,0 +1,93 @@
package net.shyshkin.study.fullstack.supportportal.backend.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.shyshkin.study.fullstack.supportportal.backend.domain.HttpResponse;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Professor;
import net.shyshkin.study.fullstack.supportportal.backend.domain.dto.ProfessorDto;
import net.shyshkin.study.fullstack.supportportal.backend.service.ProfessorService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import java.util.UUID;
import static org.springframework.http.HttpStatus.OK;
@Slf4j
@RestController
@RequestMapping("professor")
@RequiredArgsConstructor
public class ProfessorResource {
private final ProfessorService professorService;
@GetMapping("home")
public String showProfessor() {
return "Application works";
}
@PostMapping("register")
public Professor register(@RequestBody Professor professor) {
return professorService.register(professor.getFirstName(), professor.getLastName(), professor.getEmail(), professor.getDepartment(), professor.getPosition());
}
@PostMapping("add")
public ResponseEntity<Professor> addNewProfessor(@Valid ProfessorDto professorDto) {
log.debug("Professor DTO: {}", professorDto);
Professor professor = professorService.addNewProfessor(professorDto);
return ResponseEntity.ok(professor);
}
@PutMapping("{professorId}")
public Professor updateProfessor(@PathVariable UUID professorId, @Valid ProfessorDto professorDto) {
log.debug("Professor DTO: {}", professorDto);
return professorService.updateProfessor(professorId, professorDto);
}
@GetMapping("{professorId}")
public Professor findProfessorById(@PathVariable UUID professorId) {
return professorService.findByProfessorId(professorId);
}
@GetMapping("email/{email}")
public Professor findProfessorByEmail(@PathVariable String email) {
return professorService.findByEmail(email);
}
@GetMapping
public Page<Professor> getAllProfessors(Pageable pageable) {
return professorService.findAll(pageable);
}
@DeleteMapping("{professorId}")
public HttpResponse deleteProfessor(@PathVariable UUID professorId) {
professorService.deleteProfessor(professorId);
return HttpResponse.builder()
.httpStatusCode(OK.value())
.httpStatus(OK)
.reason(OK.getReasonPhrase())
.message("Professor deleted successfully")
.build();
}
@PutMapping("{professorId}/profile-image")
public Professor updateProfileImage(@PathVariable UUID professorId, @RequestParam MultipartFile profileImage) {
return professorService.updateProfileImage(professorId, profileImage);
}
@GetMapping(path = "{professorId}/profile-image/{filename}", produces = MediaType.IMAGE_JPEG_VALUE)
public byte[] getProfileImageByProfessorId(@PathVariable UUID professorId, @PathVariable String filename) {
return professorService.getImageByProfessorId(professorId, filename);
}
@GetMapping(path = "{professorId}/profile-image", produces = MediaType.IMAGE_JPEG_VALUE)
public byte[] getDefaultProfileImage(@PathVariable UUID professorId) {
return professorService.getDefaultProfileImage(professorId);
}
}

View File

@ -0,0 +1,198 @@
// package com.example.tamilnadureservoir.controller;
package net.shyshkin.study.fullstack.supportportal.backend.controller;
import java.io.StringReader;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import net.shyshkin.study.fullstack.supportportal.backend.domain.ConferenceData;
import net.shyshkin.study.fullstack.supportportal.backend.repository.ConferenceDataRepository;
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/soap")
public class SoapController {
private final RestTemplate restTemplate;
private final ConferenceDataRepository conferenceDataRepository;
@Autowired
public SoapController(RestTemplate restTemplate, ConferenceDataRepository conferenceDataRepository) {
this.restTemplate = restTemplate;
this.conferenceDataRepository = conferenceDataRepository;
}
@PostMapping("/insertConferenceData")
public ResponseEntity<String> insertConferenceData(@RequestBody ConferenceData conferenceData) {
try {
// Save the conferenceData object to the database
ConferenceData savedConferenceData = conferenceDataRepository.save(conferenceData);
return new ResponseEntity<>("ConferenceData inserted with ID: " + savedConferenceData.getId(),
HttpStatus.CREATED);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>("Failed to insert ConferenceData: " + e.getMessage(),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/getAllConferenceData")
public ResponseEntity<List<ConferenceData>> getAllConferenceData() {
List<ConferenceData> conferenceDataList = conferenceDataRepository.findAll();
return new ResponseEntity<>(conferenceDataList, HttpStatus.OK);
}
@PutMapping("/updateConferenceData/{id}")
public ResponseEntity<ConferenceData> updateConferenceData(@PathVariable Long id,
@RequestBody ConferenceData updatedData) {
// Implement the logic to update conference data by ID
Optional<ConferenceData> existingData = conferenceDataRepository.findById(id);
if (existingData.isPresent()) {
ConferenceData dataToUpdate = existingData.get();
// Update the fields of dataToUpdate with values from updatedData
// e.g., dataToUpdate.setName(updatedData.getName());
// ...
// Save the updated data
conferenceDataRepository.save(dataToUpdate);
return new ResponseEntity<>(dataToUpdate, HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@PatchMapping("/partialUpdateConferenceData/{id}")
public ResponseEntity<ConferenceData> partialUpdateConferenceData(@PathVariable Long id,
@RequestBody Map<String, Object> updates) {
// Implement the logic to partially update conference data by ID
Optional<ConferenceData> existingData = conferenceDataRepository.findById(id);
if (existingData.isPresent()) {
ConferenceData dataToUpdate = existingData.get();
// Apply updates from the request body to dataToUpdate
for (Map.Entry<String, Object> entry : updates.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// Update specific fields based on the key-value pairs
// e.g., if (key.equals("name")) dataToUpdate.setName((String) value);
// ...
}
// Save the partially updated data
conferenceDataRepository.save(dataToUpdate);
return new ResponseEntity<>(dataToUpdate, HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@DeleteMapping("/deleteConferenceData/{id}")
public ResponseEntity<Void> deleteConferenceData(@PathVariable Long id) {
// Implement the logic to delete conference data by ID
conferenceDataRepository.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@GetMapping("/getConferenceDataByPhone/{phone}")
public ResponseEntity<Object> getConferenceDataByPhone(@PathVariable("phone") String phone) {
Optional<ConferenceData> conferenceDataOptional = conferenceDataRepository.findByPhone(phone);
if (conferenceDataOptional.isPresent()) {
ConferenceData conferenceData = conferenceDataOptional.get();
return new ResponseEntity<>(conferenceData, HttpStatus.OK);
} else {
return new ResponseEntity<>("ConferenceData not found for phone: " + phone, HttpStatus.NOT_FOUND);
}
}
@PostMapping(value = "/callWebService", consumes = "application/soap+xml", produces = MediaType.APPLICATION_XML_VALUE)
public String callWebService(
@RequestBody String soapRequest,
@RequestHeader("Content-Type") String contentType,
@RequestHeader("SOAPAction") String soapAction) {
// Log or use the 'Content-Type' and 'SOAPAction' headers as needed
System.out.println("Content-Type: " + contentType);
System.out.println("SOAPAction: " + soapAction);
// Specify the SOAP action for your ASMX web service
String soapActionValue = soapAction;
String url = "https://clin.cmcvellore.ac.in/newconference/ConferencePay.asmx";
try {
// Create a DocumentBuilder to parse the SOAP request string
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document requestDoc = builder.parse(new InputSource(new StringReader(soapRequest)));
// Create a DOMSource from the parsed SOAP request
DOMSource requestSource = new DOMSource(requestDoc);
// Create a DOMResult to capture the response
DOMResult responseResult = new DOMResult();
// Set the Content-Type header to specify the SOAP format
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_XML);
// Set the SOAPAction header to specify the SOAP action
headers.set("SOAPAction", soapActionValue);
// Create a HttpEntity with the headers
HttpEntity<DOMSource> httpEntity = new HttpEntity<>(requestSource, headers);
// Send the SOAP request to the external ASMX web service
ResponseEntity<String> responseEntity = restTemplate.exchange(
url,
HttpMethod.POST,
httpEntity,
String.class);
// Extract the response XML from the ResponseEntity
String responseXml = responseEntity.getBody();
// Handle the SOAP response as needed
return responseXml;
} catch (Exception e) {
// Handle exceptions
e.printStackTrace(); // You can log the exception details
return null; // Return an appropriate response or handle differently
}
}
}

View File

@ -1,5 +1,6 @@
package net.shyshkin.study.fullstack.supportportal.backend.controller;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.shyshkin.study.fullstack.supportportal.backend.constant.SecurityConstants;
@ -32,6 +33,13 @@ import static org.springframework.http.HttpStatus.OK;
@RequiredArgsConstructor
public class UserResource {
@Data
public static class UserDTO{
String username;
String password;
}
private final UserService userService;
private final AuthenticationManager authenticationManager;
private final JwtTokenProvider jwtTokenProvider;
@ -47,7 +55,8 @@ public class UserResource {
}
@PostMapping("login")
public ResponseEntity<User> login(@RequestBody User user) {
public ResponseEntity<User> login(@RequestBody UserDTO user) {
// public ResponseEntity<User> login(@RequestBody User user) {
authenticate(user.getUsername(), user.getPassword());
User byUsername = userService.findByUsername(user.getUsername());

View File

@ -0,0 +1,45 @@
package net.shyshkin.study.fullstack.supportportal.backend.domain;
import javax.persistence.*;
import java.time.LocalDateTime;
@MappedSuperclass
public abstract class BaseEntity {
@Column(nullable = false, updatable = false)
private LocalDateTime createdDate;
@Column(nullable = false)
private LocalDateTime updatedDate;
@Column(nullable = false)
private boolean isDeleted = false;
@PrePersist
protected void onCreate() {
createdDate = LocalDateTime.now();
updatedDate = LocalDateTime.now();
}
@PreUpdate
protected void onUpdate() {
updatedDate = LocalDateTime.now();
}
public LocalDateTime getCreatedDate() {
return createdDate;
}
public LocalDateTime getUpdatedDate() {
return updatedDate;
}
public boolean isDeleted() {
return isDeleted;
}
public void setDeleted(boolean deleted) {
isDeleted = deleted;
}
}

View File

@ -0,0 +1,68 @@
package net.shyshkin.study.fullstack.supportportal.backend.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.Data;
@Entity
@Data
public class ConferenceData {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// Request fields
private String conferencecode;
private String conferenceyear;
private String bankname;
private String remoteip;
private String regno;
private String candidatename;
private String nameinreceipt;
private String address1;
private String address2;
private String city;
private String state;
private String country;
private String pincode;
private String phone;
private String mobile;
private String email;
private String foodtype;
private String participanttype;
private String practicetype;
private String accompanymembers;
private String paymentamount;
private String ToWards;
private String Allow80G;
private String PanCardNo;
private String hasgst;
private String GSTReg;
private String gstnumber;
private String gstmobileno;
private String gstemailid;
private String inputcaption1;
private String inputvalue1;
private String inputcaption2;
private String inputvalue2;
private String inputcaption3;
private String inputvalue3;
private String inputcaption4;
private String inputvalue4;
private String inputcaption5;
private String inputvalue5;
// Response fields
private String responseTransid;
private String responseResultCode;
private String responseResult;
private String responseURL;
// Constructors, getters, and setters
// You can generate getters and setters for each field using your IDE or
// manually.
}

View File

@ -0,0 +1,86 @@
package net.shyshkin.study.fullstack.supportportal.backend.domain;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;
import javax.persistence.*;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "events")
public class Event {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String code;
@Column(nullable = false)
private String year;
@Column(nullable = false)
private String subject;
@Column(nullable = false)
private String title;
private String subTitle;
@Column(nullable = false)
private String date;
@ElementCollection
@CollectionTable(name = "venues", joinColumns = @JoinColumn(name = "event_id"))
private List<Venue> venue;
@ElementCollection
@CollectionTable(name = "highlights", joinColumns = @JoinColumn(name = "event_id"))
private List<String> highlights;
@ElementCollection
@CollectionTable(name = "organisers", joinColumns = @JoinColumn(name = "event_id"))
private List<String> organisers;
// @ElementCollection
// @CollectionTable(name = "fees", joinColumns = @JoinColumn(name = "event_id"))
// private List<Fee> fee;
@Column(nullable = false)
private String phone;
@Column(nullable = false)
private String email;
@Column(nullable = false)
private Boolean isActive;
@ManyToMany
@JoinTable(
name = "event_professors",
joinColumns = @JoinColumn(name = "event_id"),
inverseJoinColumns = @JoinColumn(name = "professor_id")
)
private List<Professor> professors;
// Assuming you have these classes defined as well
@Embeddable
public static class Venue {
private String title;
private String date;
private String address;
private String info;
}
@Embeddable
public static class Fee {
private String desc;
private Integer cost;
}
}

View File

@ -0,0 +1,41 @@
package net.shyshkin.study.fullstack.supportportal.backend.domain;
import javax.persistence.*;
import java.util.List;
import lombok.*;
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode(callSuper = true)
public class Post extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(columnDefinition = "LONGTEXT", nullable = false)
private String content;
@ManyToMany
@JoinTable(
name = "post_professors",
joinColumns = @JoinColumn(name = "post_id"),
inverseJoinColumns = @JoinColumn(name = "professor_id")
)
private List<Professor> professors;
@Column(nullable = false)
private boolean isPosted;
@ElementCollection
@CollectionTable(name = "post_tags", joinColumns = @JoinColumn(name = "post_id"))
@Column(name = "tag")
private List<String> tags;
}

View File

@ -0,0 +1,53 @@
package net.shyshkin.study.fullstack.supportportal.backend.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
import org.hibernate.annotations.Type;
import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Builder
public class Professor implements Serializable {
private static final long serialVersionUID = -4372214856545239049L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
// @EqualsAndHashCode.Include
// @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private Long id;
@Type(type = "org.hibernate.type.UUIDCharType")
@Column(length = 36, columnDefinition = "varchar(36)", updatable = false, nullable = false)
private UUID professorId;
private String firstName;
private String lastName;
private String email;
private String department;
private String position;
private String officeLocation;
private LocalDateTime joinDate;
private String profileImageUrl;
@Enumerated(EnumType.STRING)
private WorkingStatus status; // Use enum to track detailed working status
@ManyToMany(mappedBy = "professors")
@JsonIgnore
private List<Post> posts;
}

View File

@ -0,0 +1,7 @@
package net.shyshkin.study.fullstack.supportportal.backend.domain;
public enum WorkingStatus {
ACTIVE,
ON_LEAVE,
RETIRED
}

View File

@ -0,0 +1,37 @@
package net.shyshkin.study.fullstack.supportportal.backend.domain.dto;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PostDto {
@NotNull
private String title;
@NotNull
private String content;
@NotEmpty(message = "At least one professor must be selected.")
private List<Long> professors;
private List<String> tags;
private boolean posted;
// Getters and setters
// ...
}

View File

@ -0,0 +1,37 @@
package net.shyshkin.study.fullstack.supportportal.backend.domain.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Role;
import net.shyshkin.study.fullstack.supportportal.backend.domain.WorkingStatus;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDateTime;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ProfessorDto {
@NotEmpty(message = "Should not be empty")
private String firstName;
private String lastName;
private String email;
private String department;
private String position;
private String officeLocation;
private WorkingStatus status;
private LocalDateTime joinDate;
private MultipartFile profileImage; // Optional field for profile image URL
}

View File

@ -0,0 +1,8 @@
package net.shyshkin.study.fullstack.supportportal.backend.exception.domain;
public class ProfessorNotFoundException extends RuntimeException {
public ProfessorNotFoundException(String message) {
super(message);
}
}

View File

@ -0,0 +1,32 @@
package net.shyshkin.study.fullstack.supportportal.backend.mapper;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Professor;
import net.shyshkin.study.fullstack.supportportal.backend.domain.dto.ProfessorDto;
import net.shyshkin.study.fullstack.supportportal.backend.domain.WorkingStatus;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
@Mapper
public interface ProfessorMapper {
// @Mapping(target = "professorId", ignore = true) // Auto-generated
@Mapping(target = "joinDate", expression = "java(java.time.LocalDateTime.now())") // Default value
@Mapping(target = "status", source = "status", qualifiedByName = "stringToWorkingStatus")
Professor toEntity(ProfessorDto professorDto);
@Mapping(target = "profileImage", ignore = true) // Ignore profileImage mapping
@Mapping(target = "status", source = "status", qualifiedByName = "workingStatusToString")
ProfessorDto toDto(Professor professor);
@Named("stringToWorkingStatus")
default WorkingStatus stringToWorkingStatus(String status) {
return status == null ? null : WorkingStatus.valueOf(status);
}
@Named("workingStatusToString")
default String workingStatusToString(WorkingStatus status) {
return status == null ? null : status.name();
}
}

View File

@ -0,0 +1,49 @@
package net.shyshkin.study.fullstack.supportportal.backend.mapper;
// import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "YourSoapRequest")
public class YourSoapRequest {
private String conferencecode;
private String conferenceyear;
private String bankname;
private String remoteip;
private String regno;
private String candidatename;
private String nameinreceipt;
private String address1;
private String address2;
private String city;
private String state;
private String country;
private String pincode;
private String phone;
private String mobile;
private String email;
private String foodtype;
private String participanttype;
private String practicetype;
private String accompanymembers;
private String paymentamount;
private String ToWards;
private String Allow80G;
private String PanCardNo;
private String hasgst;
private String GSTReg;
private String gstnumber;
private String gstmobileno;
private String gstemailid;
private String inputcaption1;
private String inputvalue1;
private String inputcaption2;
private String inputvalue2;
private String inputcaption3;
private String inputvalue3;
private String inputcaption4;
private String inputvalue4;
private String inputcaption5;
private String inputvalue5;
// Add getters and setters for each property
}

View File

@ -0,0 +1,15 @@
package net.shyshkin.study.fullstack.supportportal.backend.repository;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import net.shyshkin.study.fullstack.supportportal.backend.domain.ConferenceData;
// import org.springframework.data.rest.core.annotation.RepositoryRestResource;
// @RepositoryRestResource(path = "conferences")
public interface ConferenceDataRepository extends JpaRepository<ConferenceData, Long> {
Optional<ConferenceData> findByPhone(String phone); // Change 'phone' to your actual field name
}

View File

@ -0,0 +1,11 @@
package net.shyshkin.study.fullstack.supportportal.backend.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Event;
@Repository
public interface EventRepository extends JpaRepository<Event, Long> {
// Custom query methods can be added here if needed
}

View File

@ -0,0 +1,28 @@
package net.shyshkin.study.fullstack.supportportal.backend.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Post;
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
// Additional query methods can be defined here if needed
// 1. Find all posts where isPosted is true
List<Post> findAllByIsPostedTrue();
// 3. Find all posts associated with a specific tag where isPosted is true
@Query("SELECT p FROM Post p JOIN p.tags t WHERE t = :tag AND p.isPosted = true")
List<Post> findAllByTagAndIsPostedTrue(@Param("tag") String tag);
// Custom query to count unique tags
@Query("SELECT t, COUNT(t) FROM Post p JOIN p.tags t GROUP BY t")
List<Object[]> findTagsWithCount();
}

View File

@ -0,0 +1,27 @@
package net.shyshkin.study.fullstack.supportportal.backend.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
// import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import java.util.Optional;
import java.util.UUID;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Professor;
// @RepositoryRestResource(collectionResourceRel = "professors", path = "professors")
public interface ProfessorRepository extends JpaRepository<Professor, Long> {
@Query("SELECT p FROM Professor p WHERE p.email = :email")
Optional<Professor> findByEmail(@Param("email") String email);
@Query("SELECT CASE WHEN COUNT(p) > 0 THEN TRUE ELSE FALSE END FROM Professor p WHERE p.email = :email")
Boolean existsByEmail(@Param("email") String email);
Boolean existsByProfessorId(UUID professorId);
@Query("SELECT p FROM Professor p WHERE p.professorId = :professorId")
Optional<Professor> findByProfessorId(@Param("professorId") UUID professorId);
}

View File

@ -18,7 +18,6 @@ public class EmailService {
private final Environment environment;
public void sendNewPasswordEmail(String firstName, String password, String email) {
// Create a Simple MailMessage.
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(email);
@ -35,7 +34,20 @@ public class EmailService {
message.setSubject(EMAIL_SUBJECT);
message.setText("Hello " + firstName + "!\n\nYour new account password is: " + password + "\n\nThe Support Team");
// Log the email details before sending
log.info("Preparing to send email:");
log.info("From: {}", message.getFrom());
log.info("To: {}", String.join(", ", message.getTo()));
log.info("Cc: {}", String.join(", ", message.getCc()));
log.info("Subject: {}", message.getSubject());
log.info("Text: {}", message.getText());
try {
// Send Message!
this.emailSender.send(message);
log.info("Email successfully sent to {}", email);
} catch (Exception e) {
log.error("Failed to send email to {}. Error: {}", email, e.getMessage());
}
}
}

View File

@ -0,0 +1,32 @@
package net.shyshkin.study.fullstack.supportportal.backend.service;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Professor;
import net.shyshkin.study.fullstack.supportportal.backend.domain.dto.ProfessorDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;
import java.util.UUID;
public interface ProfessorService {
Professor register(String firstName, String lastName, String email, String department, String position);
Page<Professor> findAll(Pageable pageable);
Professor findByEmail(String email);
Professor findByProfessorId(UUID professorId);
Professor addNewProfessor(ProfessorDto professorDto);
Professor updateProfessor(UUID professorId, ProfessorDto professorDto);
void deleteProfessor(UUID professorId);
Professor updateProfileImage(UUID professorId, MultipartFile profileImage);
byte[] getImageByProfessorId(UUID professorId, String filename);
byte[] getDefaultProfileImage(UUID professorId);
}

View File

@ -0,0 +1,237 @@
package net.shyshkin.study.fullstack.supportportal.backend.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.shyshkin.study.fullstack.supportportal.backend.domain.Professor;
import net.shyshkin.study.fullstack.supportportal.backend.domain.dto.ProfessorDto;
import net.shyshkin.study.fullstack.supportportal.backend.exception.domain.EmailExistsException;
import net.shyshkin.study.fullstack.supportportal.backend.exception.domain.NotAnImageFileException;
import net.shyshkin.study.fullstack.supportportal.backend.exception.domain.ProfessorNotFoundException;
import net.shyshkin.study.fullstack.supportportal.backend.mapper.ProfessorMapper;
import net.shyshkin.study.fullstack.supportportal.backend.repository.ProfessorRepository;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.RequestEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.boot.web.client.RestTemplateBuilder;
import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import static net.shyshkin.study.fullstack.supportportal.backend.constant.FileConstant.*;
import static org.springframework.http.MediaType.*;
@Slf4j
@Service
@RequiredArgsConstructor
public class ProfessorServiceImpl implements ProfessorService {
public static final String EMAIL_NOT_FOUND_MSG = "Professor with email `%s` not found";
public static final String EMAIL_EXISTS_MSG = "Professor with email `%s` is already registered";
public static final String PROFESSOR_NOT_FOUND_MSG = "Professor not found";
private final ProfessorRepository professorRepository;
private final PasswordEncoder passwordEncoder;
private final EmailService emailService;
private final ProfessorMapper professorMapper;
private final ProfileImageService profileImageService;
private final RestTemplateBuilder restTemplateBuilder;
private RestTemplate restTemplate;
@PostConstruct
void init() {
restTemplate = restTemplateBuilder
.rootUri(TEMP_PROFILE_IMAGE_BASE_URL)
.build();
}
@Override
@Transactional
public Professor register(String firstName, String lastName, String email, String department, String position) {
ProfessorDto professorDto = ProfessorDto.builder()
.firstName(firstName)
.lastName(lastName)
.email(email)
.department(department)
.position(position)
.build();
return addNewProfessor(professorDto);
}
private String generateDefaultProfileImageUrl(UUID professorId) {
return ServletUriComponentsBuilder.fromCurrentContextPath()
.path(String.format(DEFAULT_USER_IMAGE_URI_PATTERN, professorId))
.toUriString();
}
private String generateProfileImageUrl(UUID professorId) {
return ServletUriComponentsBuilder.fromCurrentContextPath()
.path(String.format(DEFAULT_USER_IMAGE_URI_PATTERN, professorId))
.pathSegment(USER_IMAGE_FILENAME)
.toUriString();
}
@Override
public Page<Professor> findAll(Pageable pageable) {
return professorRepository.findAll(pageable);
}
@Override
public Professor findByEmail(String email) {
return professorRepository
.findByEmail(email)
.orElseThrow(() -> new EmailExistsException(String.format(EMAIL_NOT_FOUND_MSG, email)));
}
@Override
public Professor findByProfessorId(UUID professorId) {
return professorRepository
.findByProfessorId(professorId)
.orElseThrow(() -> new ProfessorNotFoundException(PROFESSOR_NOT_FOUND_MSG));
}
private void saveProfileImage(Professor professor, MultipartFile profileImage) {
if (profileImage == null) return;
if (!List.of(IMAGE_JPEG_VALUE, IMAGE_GIF_VALUE, IMAGE_PNG_VALUE).contains(profileImage.getContentType())) {
throw new NotAnImageFileException(profileImage.getOriginalFilename() + " is not an image file. Please upload an image");
}
String imageUrl = profileImageService.persistProfileImage(professor.getProfessorId(), profileImage, USER_IMAGE_FILENAME);
if (imageUrl == null)
imageUrl = generateProfileImageUrl(professor.getProfessorId());
professor.setProfileImageUrl(imageUrl);
professorRepository.save(professor);
}
private void clearProfessorStorage(Professor professor) {
profileImageService.clearUserStorage(professor.getProfessorId());
}
private UUID generateUuid() {
return UUID.randomUUID();
}
@Override
public Professor addNewProfessor(ProfessorDto professorDto) {
validateNewEmail(professorDto.getEmail());
Professor professor = professorMapper.toEntity(professorDto);
// Set a unique identifier for the professor
professor.setProfessorId(generateUuid());
// professor.setProfessorId(UUID.randomUUID()); // Set a unique identifier for the professor
professor.setJoinDate(LocalDateTime.now()); // Set join date if not provided
professor.setProfileImageUrl(generateDefaultProfileImageUrl(professor.getProfessorId()));
professorRepository.save(professor);
// saveProfileImage(professor, professorDto.getProfileImage());
return professor;
}
@Override
public Professor updateProfessor(UUID professorId, ProfessorDto professorDto) {
Professor professor = professorRepository.findByProfessorId(professorId)
.orElseThrow(() -> new RuntimeException("Professor not found with id: " + professorId));
validateUpdateEmail(professorId,professorDto.getEmail());
professor.setFirstName(professorDto.getFirstName());
professor.setLastName(professorDto.getLastName());
professor.setEmail(professorDto.getEmail());
professor.setDepartment(professorDto.getDepartment());
professor.setPosition(professorDto.getPosition());
professor.setOfficeLocation(professorDto.getOfficeLocation());
professor.setStatus(professorDto.getStatus());
professor.setJoinDate(professorDto.getJoinDate()); // Update join date if provided
professorRepository.save(professor);
saveProfileImage(professor, professorDto.getProfileImage());
return professor;
}
@Override
public void deleteProfessor(UUID professorId) {
Professor professorToBeDeleted = professorRepository
.findByProfessorId(professorId)
.orElseThrow(() -> new ProfessorNotFoundException(PROFESSOR_NOT_FOUND_MSG));
clearProfessorStorage(professorToBeDeleted);
professorRepository.delete(professorToBeDeleted);
}
@Override
public Professor updateProfileImage(UUID professorId, MultipartFile profileImage) {
Professor professor = findByProfessorId(professorId);
saveProfileImage(professor, profileImage);
return professor;
}
@Override
public byte[] getImageByProfessorId(UUID professorId, String filename) {
if (!professorRepository.existsByProfessorId(professorId)) {
throw new ProfessorNotFoundException(PROFESSOR_NOT_FOUND_MSG);
}
return profileImageService.retrieveProfileImage(professorId, filename);
}
@Override
public byte[] getDefaultProfileImage(UUID professorId) {
if (!professorRepository.existsByProfessorId(professorId)) {
throw new ProfessorNotFoundException(PROFESSOR_NOT_FOUND_MSG);
}
RequestEntity<Void> requestEntity = RequestEntity
.get("/{professorId}", professorId)
.accept(IMAGE_JPEG)
.build();
var responseEntity = restTemplate.exchange(requestEntity, new ParameterizedTypeReference<byte[]>() {});
return responseEntity.getBody();
}
private void validateNewEmail(String email) {
if (professorRepository.existsByEmail(email)) {
throw new EmailExistsException(String.format(EMAIL_EXISTS_MSG, email));
}
}
private Professor validateUpdateEmail(UUID professorId, String email) {
Objects.requireNonNull(professorId);
Professor currentProfessor = findByProfessorId(professorId);
if (!Objects.equals(currentProfessor.getEmail(), email) && professorRepository.existsByEmail(email)) {
throw new EmailExistsException(String.format(EMAIL_EXISTS_MSG, email));
}
return currentProfessor;
}
}

View File

@ -35,3 +35,5 @@ public interface UserService extends UserDetailsService {
byte[] getDefaultProfileImage(UUID userId);
}

View File

@ -8,6 +8,7 @@ import net.shyshkin.study.fullstack.supportportal.backend.domain.UserPrincipal;
import net.shyshkin.study.fullstack.supportportal.backend.domain.dto.UserDto;
import net.shyshkin.study.fullstack.supportportal.backend.exception.domain.*;
import net.shyshkin.study.fullstack.supportportal.backend.mapper.UserMapper;
import net.shyshkin.study.fullstack.supportportal.backend.repository.ProfessorRepository;
import net.shyshkin.study.fullstack.supportportal.backend.repository.UserRepository;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.boot.web.client.RestTemplateBuilder;
@ -45,6 +46,7 @@ public class UserServiceImpl implements UserService {
public static final String EMAIL_EXISTS_MSG = "User with email `%s` is already registered";
private final UserRepository userRepository;
private final ProfessorRepository professorRepository;
private final PasswordEncoder passwordEncoder;
private final LoginAttemptService loginAttemptService;
private final EmailService emailService;
@ -264,10 +266,14 @@ public class UserServiceImpl implements UserService {
@Override
public byte[] getDefaultProfileImage(UUID userId) {
if (!userRepository.existsByUserId(userId)) {
if (!userRepository.existsByUserId(userId) && !professorRepository.existsByProfessorId(userId)) {
throw new UserNotFoundException(USER_NOT_FOUND_MSG);
}
// if (!professorRepository.existsByProfessorId(userId)) {
// throw new UserNotFoundException(USER_NOT_FOUND_MSG);
// }
// "https://robohash.org/11951691-d373-4126-bef2-84d157a6546b"
RequestEntity<Void> requestEntity = RequestEntity
.get("/{userId}", userId)

View File

@ -4,25 +4,29 @@ server:
# whitelabel:
# enabled: false
spring:
mail:
host: smtp.gmail.com
host: mail.techzoos.in
port: 587
username: ${PORTAL_MAIL_USERNAME:fake.user@gmail.com}
password: ${PORTAL_MAIL_PASSWORD:fake_password}
username: ${PORTAL_MAIL_USERNAME:govardhan@techzoos.in}
password: ${PORTAL_MAIL_PASSWORD:123456}
properties:
mail:
transport:
protocol: smtp
smtp:
auth: true
auth: false
starttls:
enable: true
ssl:
enable: false
datasource:
url: jdbc:mysql://210.18.189.94:8098/demo
username: youruser
password: youruserpassword
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://mysql:3306/support-portal
username: ENC(criE3etnc/EVZbizNgNdmj+8F0BYC3bSVBK1VT/xJ7WMoNvSfdEGsqWfCpaX5lEWvXLOO8pzgjdB5zIOBcTikw==)
password: ENC(OTG4nZfio2dHHxV0Ey/Nmb4XeEfaD1YMsRVQxOwF59Q1JSBZPUKLWXORJXPz2RysKRngcdk2SgioAMw166DoqA==)
jpa:
hibernate:
ddl-auto: update
@ -39,87 +43,100 @@ spring:
web:
resources:
add-mappings: false
app:
public-urls: /user/login,/user/register,/user/*/profile-image/**
public-urls: /user/login,/user/register,/user/*/profile-image/**,/professors,/professors/**
cors:
allowed-origins: http://localhost:4200,https://localhost:4200,http://art-support-portal.s3-website.eu-north-1.amazonaws.com,http://portal.shyshkin.net
allowed-origins: http://localhost:4200,https://localhost:4200,http://art-support-portal.s3-website.eu-north-1.amazonaws.com,http://portal.shyshkin.net,*
jwt:
secret: ENC(EfWSJqncgjSJ0g/tMzLoO9PlrjmpQf8Eb+q51SUXlh3AzwMHJyTF1gV0VpuNEQkNb9Lsw62xOBnxDNe73BsPDQ==)
secret: custom_text
# secret: ${random.value} #Does not work - every time generates new value
jasypt:
encryptor:
password: ${JASYPT_PASSWORD}
algorithm: PBEWITHHMACSHA512ANDAES_256
iv-generator-classname: org.jasypt.iv.RandomIvGenerator
# jasypt:
# encryptor:
# # password: ${JASYPT_PASSWORD}
# password: custom_text
# algorithm: PBEWITHHMACSHA512ANDAES_256
# iv-generator-classname: org.jasypt.iv.RandomIvGenerator
---
spring:
config:
activate:
on-profile: local
datasource:
url: jdbc:mysql://localhost:23306/support-portal
jpa:
show-sql: true
logging:
level:
net.shyshkin: debug
# spring:
# config:
# activate:
# on-profile: local
# datasource:
# url: jdbc:mysql://210.18.189.94:8098/demo
# username: youruser
# password: youruserpassword
# jpa:
# show-sql: true
# logging:
# level:
# net.shyshkin: debug
---
spring:
config:
activate:
on-profile: aws-local
datasource:
url: jdbc:mysql://localhost:3306/support_portal
username: support_portal_user
password: Supp0rt_Porta!_P@ssword
mail:
host: email-smtp.eu-north-1.amazonaws.com
port: 587
username: AKIAVW7XGDOWFHHCELIH
password: BJyWOWS1xWYR35MRCFn3BuuQ6vY+k7DRsdAvOfqDs/Fk
# spring:
# config:
# activate:
# on-profile: aws-local
# datasource:
# url: jdbc:mysql://210.18.189.94:8098/demo
# username: youruser
# password: youruserpassword
# mail:
# host: email-smtp.eu-north-1.amazonaws.com
# port: 587
# username: AKIAVW7XGDOWFHHCELIH
# password: BJyWOWS1xWYR35MRCFn3BuuQ6vY+k7DRsdAvOfqDs/Fk
# we want to test (1) from localhost, (2) from S3 bucket Static Web Site, (3) from our EC2 instance
app:
email:
from: d.art.shishkin@gmail.com
carbon-copy: d.art.shishkin@gmail.com
cors:
allowed-origins: http://localhost:4200,http://art-support-portal.s3-website.eu-north-1.amazonaws.com,http://support-portal.shyshkin.net,http://portal.shyshkin.net
server:
port: 5000
logging:
level:
net.shyshkin: debug
# app:
# email:
# from: d.art.shishkin@gmail.com
# carbon-copy: d.art.shishkin@gmail.com
# cors:
# allowed-origins: http://localhost:4200,http://art-support-portal.s3-website.eu-north-1.amazonaws.com,http://support-portal.shyshkin.net,http://portal.shyshkin.net
# server:
# port: 5000
# logging:
# level:
# net.shyshkin: debug
---
spring:
config:
activate:
on-profile: aws-rds
datasource:
url: jdbc:mysql://portal-db.coaum9neetxc.eu-north-1.rds.amazonaws.com:3306/support_portal
username: ENC(MPap/iQmyyLSeulVzLLq4nQ5dcwMyJ1cbW+bW7MOU4pN7CHQULbaDn8/5VszOP9F)
password: ENC(nC0PV+0wPW+73o2uOh4Zg7EA34vdwZKpkPD4CIKvjDDXQ+dGXjykTuHUl3jlxkRC/00IpFurk/UJ9hTpZ6QqGA==)
mail:
host: email-smtp.eu-north-1.amazonaws.com
port: 587
username: ENC(CgaSXOMqTmswes1PgAYp3ICcoIVVXyKUlDR1Se963Vja02cBIor/2884e2OEFKW4XhBClTbuZCVdHK0vRRNqYg==)
password: ENC(GA8XsfU8vmat/7A8qEhrVz0Y47THxNT8jQ29wSg035fozwW7m+fKhJMQd4tgxL9dPfOzSXYzkffL0fG1AihWiHl99H9iBeXndDSvOhskvh4=)
# spring:
# config:
# activate:
# on-profile: aws-rds
# datasource:
# url: jdbc:mysql://210.18.189.94:8098/demo
# username: youruser
# password: youruserpassword
# mail:
# host: email-smtp.eu-north-1.amazonaws.com
# port: 587
# username: custom_text
# password: custom_text
# we want to test (1) from localhost, (2) from S3 bucket Static Web Site, (3) from our EC2 instance
app:
email:
from: d.art.shishkin@gmail.com
carbon-copy: d.art.shishkin@gmail.com
cors:
allowed-origins: http://localhost:4200,http://art-support-portal.s3-website.eu-north-1.amazonaws.com,http://support-portal.shyshkin.net,http://portal.shyshkin.net
server:
port: 5000
logging:
level:
net.shyshkin: debug
# app:
# email:
# from: d.art.shishkin@gmail.com
# carbon-copy: d.art.shishkin@gmail.com
# cors:
# allowed-origins: http://localhost:4200,http://art-support-portal.s3-website.eu-north-1.amazonaws.com,http://support-portal.shyshkin.net,http://portal.shyshkin.net
# server:
# port: 5000
# logging:
# level:
# net.shyshkin: debug
#####
#
@ -127,37 +144,37 @@ logging:
#
#####
server.ssl:
enabled: true # Enable HTTPS support (only accept HTTPS requests)
key-alias: securedPortal # Alias that identifies the key in the key store
key-store: classpath:securedPortal-keystore.p12 # Keystore location
key-store-password: ENC(nqDHyVFmySdbaCOZfj4EiQLRYyLSPLRLq/OzncqlsFIuWvh8caiOapAb+zrKR1+A) # Keystore password
key-store-type: PKCS12 # Keystore format
# server.ssl:
# enabled: true # Enable HTTPS support (only accept HTTPS requests)
# key-alias: securedPortal # Alias that identifies the key in the key store
# key-store: classpath:securedPortal-keystore.p12 # Keystore location
# key-store-password: custom_text
# key-store-type: PKCS12 # Keystore format
---
spring:
config:
activate:
on-profile: image-s3
app:
amazon-s3:
bucket-name: portal-user-profile-images
# ---
# spring:
# config:
# activate:
# on-profile: image-s3
# app:
# amazon-s3:
# bucket-name: portal-user-profile-images
---
spring:
config:
activate:
on-profile: image-s3-localstack
app:
amazon-s3:
bucket-name: portal-user-profile-images
config:
aws:
region: eu-north-1
s3:
url: http://127.0.0.1:4566
bucket-name: portal-user-profile-images
access-key: localstack
secret-key: localstack
# ---
# spring:
# config:
# activate:
# on-profile: image-s3-localstack
# app:
# amazon-s3:
# bucket-name: portal-user-profile-images
# config:
# aws:
# region: eu-north-1
# s3:
# url: http://127.0.0.1:4566
# bucket-name: portal-user-profile-images
# access-key: localstack
# secret-key: localstack

View File

@ -114,6 +114,9 @@ class UserResourceTest extends BaseUserTest {
//when
ResponseEntity<User> responseEntity = restTemplate.postForEntity("/user/register", fakeUser, User.class);
//then
log.debug("Response Entity: {}", responseEntity);
assertThat(responseEntity.getStatusCode()).isEqualTo(OK);
@ -132,6 +135,7 @@ class UserResourceTest extends BaseUserTest {
user = registeredUser;
}
@Test
@Order(40)
void registerUser_usernameExists() {

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,13 @@
"rxjs": "~6.6.0",
"subsink": "^1.0.2",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
"zone.js": "~0.11.4",
"@nicky-lenaers/ngx-scroll-to": "^9.0.0",
"ng-particles": "^2.1.11",
"ngx-owl-carousel-o": "^5.0.0",
"ngx-typed-js": "^2.0.2",
"tsparticles": "^1.18.11",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@angular-devkit/build-angular": "~12.2.5",

View File

@ -0,0 +1,46 @@
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from "@angular/router";
import {LoginComponent} from "../component/login/login.component";
import {RegisterComponent} from "../component/register/register.component";
import {UserComponent} from "../component/user/user.component";
import {AuthenticationGuard} from "../guard/authentication.guard";
import {ManagementComponent} from "../component/management/management.component";
import {UsersComponent} from "../component/management/users/users.component";
import {SettingsComponent} from "../component/management/settings/settings.component";
import {ProfileComponent} from "../component/management/profile/profile.component";
import {UserEditComponent} from "../component/management/users/user-edit/user-edit.component";
import {UserViewComponent} from "../component/management/users/user-view/user-view.component";
import {UserResolver} from "../component/management/users/user-resolver.service";
import { ProfessorComponent } from '../component/professor/professor.component';
import { HomeComponent } from '../component/home/home.component';
import { EventComponent } from '../component/event/event.component';
import { BlogComponent } from '../component/blog/blog.component';
import { EventFormComponent } from '../component/event-form/event-form.component';
const routes: Routes = [
{ path: 'login', component: LoginComponent },
{ path: 'home', component: HomeComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'settings', component: SettingsComponent, canActivate: [AuthenticationGuard] },
{ path: 'profile', component: ProfileComponent, canActivate: [AuthenticationGuard] },
{ path: 'events', component: EventComponent, canActivate: [AuthenticationGuard] },
{ path: 'eventForm', component: EventFormComponent, canActivate: [AuthenticationGuard] },
{ path: 'eventForm/:id', component: EventFormComponent, canActivate: [AuthenticationGuard] },
{ path: 'blogs', component: BlogComponent, canActivate: [AuthenticationGuard] },
{ path: 'userManagement', component: UserComponent, canActivate: [AuthenticationGuard] },
{ path: 'professorManagement', component: ProfessorComponent, canActivate: [AuthenticationGuard] },
{
path: '',
redirectTo: 'login',
pathMatch: 'full'
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class AdminRoutingModule { }

View File

@ -0,0 +1,82 @@
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
// import {AppComponent} from '../app.component';
import {HTTP_INTERCEPTORS, HttpClientModule} from "@angular/common/http";
import {AuthenticationService} from "../service/authentication.service";
import {UserService} from "../service/user.service";
import {AuthInterceptor} from "../interceptor/auth.interceptor";
import {AuthenticationGuard} from "../guard/authentication.guard";
import {LoginComponent} from '../component/login/login.component';
import {RegisterComponent} from '../component/register/register.component';
import {UserComponent} from '../component/user/user.component';
// import {AppRoutingModule} from '../app-routing.module';
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {ManagementComponent} from '../component/management/management.component';
import {UsersComponent} from '../component/management/users/users.component';
import {SettingsComponent} from '../component/management/settings/settings.component';
import {ProfileComponent} from '../component/management/profile/profile.component';
import {UsersTableComponent} from '../component/management/users/users-table/users-table.component';
import {UserViewComponent} from '../component/management/users/user-view/user-view.component';
import {UserEditComponent} from '../component/management/users/user-edit/user-edit.component';
import { ProfessorComponent } from '../component/professor/professor.component';
import { MenuComponent } from '../component/menu/menu.component';
import { HomeComponent } from '../component/home/home.component';
import { BlogComponent } from '../component/blog/blog.component';
import { EventComponent } from '../component/event/event.component';
import { BlogService } from '../service/blog.service';
import { AngularEditorModule } from '@josipv/angular-editor-k2';
import { NotificationModule } from '../notification/notification.module';
import { EventFormComponent } from '../component/event-form/event-form.component';
import { CommonModule } from '@angular/common';
import { AdminRoutingModule } from './admin-routing.module';
// import { PagesModule } from '../pages/pages.module';
@NgModule({
declarations: [
// AppComponent,
LoginComponent,
RegisterComponent,
UserComponent,
ManagementComponent,
UsersComponent,
SettingsComponent,
ProfileComponent,
UsersTableComponent,
UserViewComponent,
UserEditComponent,
ProfessorComponent,
MenuComponent,
HomeComponent,
BlogComponent,
EventComponent,
EventFormComponent
],
imports: [
CommonModule,
// BrowserModule,
// HttpClientModule,
NotificationModule,
// AppRoutingModule,
AdminRoutingModule,
FormsModule,
ReactiveFormsModule,
AngularEditorModule,
// PagesModule,
],
// providers: [AuthenticationGuard, AuthenticationService, UserService,BlogService,
// {provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true}
// ],
// bootstrap: [AppComponent]
})
export class AdminModule { }

View File

@ -14,7 +14,7 @@ describe('routes', () => {
expect(routes).toContain({path: "register", component: RegisterComponent});
});
it('should contain a route for /user/management', () => {
it('should contain a route for /dashboard/userManagement', () => {
expect(routes).toContain({path: 'user/management', component: UserComponent, canActivate: [AuthenticationGuard]});
});

View File

@ -1,31 +1,80 @@
import { NgModule } from '@angular/core';
import {RouterModule, Routes} from "@angular/router";
import {LoginComponent} from "./component/login/login.component";
import {RegisterComponent} from "./component/register/register.component";
import {UserComponent} from "./component/user/user.component";
import {AuthenticationGuard} from "./guard/authentication.guard";
import {ManagementComponent} from "./component/management/management.component";
import {UsersComponent} from "./component/management/users/users.component";
import {SettingsComponent} from "./component/management/settings/settings.component";
import {ProfileComponent} from "./component/management/profile/profile.component";
import {UserEditComponent} from "./component/management/users/user-edit/user-edit.component";
import {UserViewComponent} from "./component/management/users/user-view/user-view.component";
import {UserResolver} from "./component/management/users/user-resolver.service";
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './component/login/login.component';
import { RegisterComponent } from './component/register/register.component';
import { UserComponent } from './component/user/user.component';
import { AuthenticationGuard } from './guard/authentication.guard';
import { ManagementComponent } from './component/management/management.component';
import { UsersComponent } from './component/management/users/users.component';
import { SettingsComponent } from './component/management/settings/settings.component';
import { ProfileComponent } from './component/management/profile/profile.component';
import { UserEditComponent } from './component/management/users/user-edit/user-edit.component';
import { UserViewComponent } from './component/management/users/user-view/user-view.component';
import { UserResolver } from './component/management/users/user-resolver.service';
import { ProfessorComponent } from './component/professor/professor.component';
import { HomeComponent } from './component/home/home.component';
import { EventComponent } from './component/event/event.component';
import { BlogComponent } from './component/blog/blog.component';
import { EventFormComponent } from './component/event-form/event-form.component';
export const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'settings', component: SettingsComponent, canActivate: [AuthenticationGuard] },
{ path: 'profile', component: ProfileComponent, canActivate: [AuthenticationGuard] },
{ path: 'events', component: EventComponent, canActivate: [AuthenticationGuard] },
{ path: 'blogs', component: BlogComponent, canActivate: [AuthenticationGuard] },
{ path: 'user/management', component: UserComponent, canActivate: [AuthenticationGuard] },
{ path: 'professor/management', component: ProfessorComponent, canActivate: [AuthenticationGuard] },
{
path: '',
loadChildren: () =>
import('./pages/pages.module').then((m) => m.PagesModule),
},
{
path: 'dashboard',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
},
{ path: '', redirectTo: '/', pathMatch: 'full' }
// { path: 'home', component: HomeComponent },
// { path: 'login', component: LoginComponent },
// { path: 'register', component: RegisterComponent },
// {
// path: 'settings',
// component: SettingsComponent,
// canActivate: [AuthenticationGuard],
// },
// {
// path: 'profile',
// component: ProfileComponent,
// canActivate: [AuthenticationGuard],
// },
// {
// path: 'events',
// component: EventComponent,
// canActivate: [AuthenticationGuard],
// },
// {
// path: 'eventForm',
// component: EventFormComponent,
// canActivate: [AuthenticationGuard],
// },
// {
// path: 'eventForm/:id',
// component: EventFormComponent,
// canActivate: [AuthenticationGuard],
// },
// {
// path: 'blogs',
// component: BlogComponent,
// canActivate: [AuthenticationGuard],
// },
// {
// path: 'user/management',
// component: UserComponent,
// canActivate: [AuthenticationGuard],
// },
// {
// path: 'professor/management',
// component: ProfessorComponent,
// canActivate: [AuthenticationGuard],
// },
// {
// path: 'management', component: ManagementComponent, canActivate: [AuthenticationGuard],
@ -41,12 +90,11 @@ export const routes: Routes = [
// }
// ]
// },
{path: '', redirectTo: '/login', pathMatch: 'full'}
// { path: '', redirectTo: '/login', pathMatch: 'full' },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
exports: [RouterModule],
})
export class AppRoutingModule {
}
export class AppRoutingModule {}

View File

@ -6,5 +6,5 @@ import {Component} from '@angular/core';
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'support-portal-frontend';
title = 'cnc - Admin';
}

View File

@ -1,4 +1,4 @@
import {NgModule} from '@angular/core';
import {Compiler, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {AppComponent} from './app.component';
@ -27,6 +27,8 @@ import { EventComponent } from './component/event/event.component';
import { BlogService } from './service/blog.service';
import { AngularEditorModule } from '@josipv/angular-editor-k2';
import { NotificationModule } from './notification/notification.module';
import { EventFormComponent } from './component/event-form/event-form.component';
// import { PagesModule } from './pages/pages.module';
@ -35,21 +37,22 @@ import { NotificationModule } from './notification/notification.module';
@NgModule({
declarations: [
AppComponent,
LoginComponent,
RegisterComponent,
UserComponent,
ManagementComponent,
UsersComponent,
SettingsComponent,
ProfileComponent,
UsersTableComponent,
UserViewComponent,
UserEditComponent,
ProfessorComponent,
MenuComponent,
HomeComponent,
BlogComponent,
EventComponent
// LoginComponent,
// RegisterComponent,
// UserComponent,
// ManagementComponent,
// UsersComponent,
// SettingsComponent,
// ProfileComponent,
// UsersTableComponent,
// UserViewComponent,
// UserEditComponent,
// ProfessorComponent,
// MenuComponent,
// HomeComponent,
// BlogComponent,
// EventComponent,
// EventFormComponent
],
imports: [
@ -57,11 +60,14 @@ import { NotificationModule } from './notification/notification.module';
HttpClientModule,
NotificationModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
AngularEditorModule
// FormsModule,
// ReactiveFormsModule,
// AngularEditorModule,
// PagesModule,
],
providers: [AuthenticationGuard, AuthenticationService, UserService,BlogService,
// providers:[],
providers: [Compiler,AuthenticationGuard, AuthenticationService, UserService,BlogService,
{provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true}
],
bootstrap: [AppComponent]

View File

@ -0,0 +1,145 @@
<app-menu></app-menu>
<div class="container mt-4">
<form [formGroup]="eventForm" (ngSubmit)="onSubmit()">
<div class="row">
<div class="col-md-6">
<div class="form-group mb-3">
<label for="code" class="form-label text-primary">Code</label>
<input id="code" formControlName="code" class="form-control" />
</div>
<div class="form-group mb-3">
<label for="year" class="form-label text-primary">Year</label>
<input id="year" formControlName="year" class="form-control" />
</div>
<div class="form-group mb-3">
<label for="subject" class="form-label text-primary">Subject</label>
<input id="subject" formControlName="subject" class="form-control" />
</div>
<div class="form-group mb-3">
<label for="title" class="form-label text-primary">Title</label>
<input id="title" formControlName="title" class="form-control" />
</div>
<div class="form-group mb-3">
<label for="subTitle" class="form-label text-primary">Subtitle</label>
<input id="subTitle" formControlName="subTitle" class="form-control" />
</div>
<div class="form-group mb-3">
<label for="date" class="form-label text-primary">Date</label>
<input id="date" formControlName="date" class="form-control" />
</div>
<div class="form-group mb-3">
<label for="phone" class="form-label text-primary">Phone</label>
<input id="phone" formControlName="phone" class="form-control" />
</div>
<div class="form-group mb-3">
<label for="email" class="form-label text-primary">Email</label>
<input id="email" formControlName="email" class="form-control" />
</div>
<div class="form-group mb-3">
<label for="isActive" class="form-label text-primary">Active</label>
<input id="isActive" type="checkbox" formControlName="isActive" />
</div>
</div>
<div class="col-md-6">
<div class="form-group mb-3">
<label class="form-label text-primary">Venues</label>
<div formArrayName="venues">
<div *ngFor="let venue of venues.controls; let i = index" class="card mb-2">
<div class="card-body">
<div [formGroupName]="i">
<div class="row mb-2">
<div class="col-12">
<input formControlName="title" placeholder="Title" class="form-control" />
</div>
</div>
<div class="row mb-2">
<div class="col-6">
<input formControlName="date" placeholder="Date" class="form-control" />
</div>
<div class="col-6">
<input formControlName="address" placeholder="Address" class="form-control" />
</div>
</div>
<div class="row mb-2">
<div class="col-12">
<input formControlName="info" placeholder="Info" class="form-control" />
</div>
</div>
</div>
<button type="button" class="btn btn-danger btn-sm float-end" (click)="removeVenue(i)">
<!-- <i class="bi bi-trash"></i> -->X
</button>
</div>
</div>
<button type="button" class="btn btn-primary" (click)="addVenue()">
<i class="bi bi-plus"></i> Add Venue
</button>
</div>
</div>
<div class="form-group mb-3">
<label class="form-label text-primary">Highlights</label>
<div formArrayName="highlights">
<div *ngFor="let highlight of highlights.controls; let i = index" class="card mb-2">
<div class="card-body">
<input [formControlName]="i" class="form-control" placeholder="Highlight" />
<button type="button" class="btn btn-danger btn-sm float-end mt-2" (click)="removeHighlight(i)">
<!-- <i class="bi bi-trash"></i> -->X
</button>
</div>
</div>
<button type="button" class="btn btn-primary" (click)="addHighlight()">
<i class="bi bi-plus"></i> Add Highlight
</button>
</div>
</div>
<div class="form-group mb-3">
<label class="form-label text-primary">Organisers</label>
<div formArrayName="organisers">
<div *ngFor="let organiser of organisers.controls; let i = index" class="card mb-2">
<div class="card-body">
<input [formControlName]="i" class="form-control" placeholder="Organiser" />
<button type="button" class="btn btn-danger btn-sm float-end mt-2" (click)="removeOrganiser(i)">
<!-- <i class="bi bi-trash"></i> -->X
</button>
</div>
</div>
<button type="button" class="btn btn-primary" (click)="addOrganiser()">
<i class="bi bi-plus"></i> Add Organiser
</button>
</div>
</div>
<div class="form-group mb-3">
<label class="form-label text-primary">Fees</label>
<div formArrayName="fees">
<div *ngFor="let fee of fees.controls; let i = index" class="card mb-2">
<div class="card-body">
<div [formGroupName]="i">
<div class="row mb-2">
<div class="col-8">
<input formControlName="desc" placeholder="Description" class="form-control" />
</div>
<div class="col-4">
<input formControlName="cost" placeholder="Cost" type="number" class="form-control" />
</div>
</div>
</div>
<button type="button" class="btn btn-danger btn-sm float-end mt-2" (click)="removeFee(i)">
<!-- <i class="bi bi-trash"></i> -->X
</button>
</div>
</div>
<button type="button" class="btn btn-primary" (click)="addFee()">
<i class="bi bi-plus"></i> Add Fee
</button>
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
</div>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { EventFormComponent } from './event-form.component';
describe('EventFormComponent', () => {
let component: EventFormComponent;
let fixture: ComponentFixture<EventFormComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ EventFormComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(EventFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,135 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { EventService } from 'src/app/service/event.service';
@Component({
selector: 'app-event-form',
templateUrl: './event-form.component.html',
styleUrls: ['./event-form.component.css']
})
export class EventFormComponent implements OnInit {
eventForm: FormGroup;
constructor(
private fb: FormBuilder,
private eventService: EventService,
private route: ActivatedRoute,
private router: Router
) {}
eventId: number | null;
ngOnInit() {
this.eventForm = this.fb.group({
code: ['', Validators.required],
year: ['', Validators.required],
subject: ['', Validators.required],
title: ['', Validators.required],
subTitle: [''],
date: ['', Validators.required],
venues: this.fb.array([]),
highlights: this.fb.array([]),
organisers: this.fb.array([]),
fees: this.fb.array([]),
phone: ['', Validators.required],
email: ['', [Validators.required, Validators.email]],
isActive: [true]
});
this.route.paramMap.subscribe(params => {
const idParam = params.get('id');
this.eventId = idParam ? +idParam : null;
if (this.eventId !== null) {
this.loadEvent(this.eventId);
}
});
}
loadEvent(id: number): void {
this.eventService.getEvent(id).subscribe(event => {
this.eventForm.patchValue(event);
this.setArrayValues('venues', event.venues);
this.setArrayValues('highlights', event.highlights);
this.setArrayValues('organisers', event.organisers);
this.setArrayValues('fees', event.fees);
});
}
setArrayValues(controlName: string, values: any[]): void {
const array = this.eventForm.get(controlName) as FormArray;
values.forEach(value => array.push(this.fb.group(value)));
}
get venues(): FormArray {
return this.eventForm.get('venues') as FormArray;
}
get highlights(): FormArray {
return this.eventForm.get('highlights') as FormArray;
}
get organisers(): FormArray {
return this.eventForm.get('organisers') as FormArray;
}
get fees(): FormArray {
return this.eventForm.get('fees') as FormArray;
}
addVenue() {
this.venues.push(this.fb.group({
title: [''],
date: [''],
address: [''],
info: ['']
}));
}
removeVenue(index: number) {
this.venues.removeAt(index);
}
addHighlight() {
this.highlights.push(this.fb.control(''));
}
removeHighlight(index: number) {
this.highlights.removeAt(index);
}
addOrganiser() {
this.organisers.push(this.fb.control(''));
}
removeOrganiser(index: number) {
this.organisers.removeAt(index);
}
addFee() {
this.fees.push(this.fb.group({
desc: [''],
cost: ['']
}));
}
removeFee(index: number) {
this.fees.removeAt(index);
}
onSubmit(): void {
if (this.eventForm.valid) {
if (this.eventId) {
this.eventService.updateEvent(this.eventId, this.eventForm.value).subscribe(() => this.router.navigate(['/events']));
} else {
this.eventService.createEvent(this.eventForm.value).subscribe(() => this.router.navigate(['/events']));
}
}
}
}

View File

@ -1,2 +1,47 @@
<app-menu></app-menu>
<div class="container mt-4">
<h2 class="mb-4">Events</h2>
<div class="mb-3">
<a routerLink="/eventForm" class="btn btn-primary">
<i class="bi bi-plus"></i> Add New Event
</a>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>Code</th>
<th>Year</th>
<th>Subject</th>
<th>Title</th>
<th>Subtitle</th>
<th>Date</th>
<th>Phone</th>
<th>Email</th>
<th>Active</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let event of events">
<td>{{ event.code }}</td>
<td>{{ event.year }}</td>
<td>{{ event.subject }}</td>
<td>{{ event.title }}</td>
<td>{{ event.subTitle }}</td>
<td>{{ event.date }}</td>
<td>{{ event.phone }}</td>
<td>{{ event.email }}</td>
<td>{{ event.isActive ? 'Yes' : 'No' }}</td>
<td>
<a [routerLink]="['/eventForm', event.id]" class="btn btn-warning btn-sm">
<i class="bi bi-pencil"></i> Edit
</a>
<button (click)="deleteEvent(event.id)" class="btn btn-danger btn-sm">
<i class="bi bi-trash"></i> Delete
</button>
</td>
</tr>
</tbody>
</table>
</div>

View File

@ -1,4 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { EventService } from 'src/app/service/event.service';
@Component({
selector: 'app-event',
@ -6,13 +9,21 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./event.component.css']
})
export class EventComponent implements OnInit {
events: any[] = []; // Define the type according to your model
constructor() { }
htmlContent: string = '';
constructor(private eventService: EventService, private router: Router) { }
ngOnInit(): void {
this.loadEvents();
}
loadEvents(): void {
this.eventService.getEvents().subscribe(events => this.events = events);
}
deleteEvent(id: number): void {
if (confirm('Are you sure you want to delete this event?')) {
// this.eventService.deleteEvent(id).subscribe(() => this.loadEvents());
}
}
}

View File

@ -28,7 +28,7 @@ export class LoginComponent implements OnInit, OnDestroy {
ngOnInit(): void {
if (this.authenticationService.isUserLoggedIn()) {
this.router.navigate(["/user", "management"]);
this.router.navigate(["/dashboard", "userManagement"]);
// this.router.navigate(["/management", "users"]);
this.notificationService.notify(NotificationType.INFO, "You are already logged in");
}
@ -46,8 +46,7 @@ export class LoginComponent implements OnInit, OnDestroy {
this.authenticationService.addUserToLocalStorage(response.body!);
this.router.navigateByUrl('/home');
// this.router.navigateByUrl('/management/users');
this.router.navigateByUrl('/dashboard/home');
this.showLoading = false;
},
(errorResponse: HttpErrorResponse) => {

View File

@ -77,7 +77,7 @@ export class ProfileComponent implements OnInit {
onLogOut() {
this.authenticationService.logout();
this.router.navigate(['/login']);
this.router.navigate(['/dashboard/login']);
this.notificationService.notify(NotificationType.SUCCESS, 'You have been successfully logged out');
}

View File

@ -22,5 +22,6 @@
</fieldset>
</form>
</div>
</div>

View File

@ -56,4 +56,5 @@ export class SettingsComponent implements OnInit, OnDestroy {
}
);
}
}

View File

@ -11,38 +11,38 @@
<nav class="navbar navbar-expand-md breadcrumb">
<div class="collapse navbar-collapse" id="navbarCollapse">
<div class="nav nav-pills">
<a class="nav-item nav-link ml-1" routerLink="/home" routerLinkActive="active" (click)="changeTitle('Home')">
<a class="nav-item nav-link ml-1" routerLink="/dashboard/home" routerLinkActive="active" (click)="changeTitle('Home')">
<i class="fa fa-home"></i>
Home
</a>
<a class="nav-item nav-link ml-1" routerLink="/user/management" routerLinkActive="active" (click)="changeTitle('Users')">
<a class="nav-item nav-link ml-1" routerLink="/dashboard/userManagement" routerLinkActive="active" (click)="changeTitle('Users')">
<i class="fa fa-users"></i>
Users
</a>
<a class="nav-item nav-link ml-1" routerLink="/professor/management" routerLinkActive="active" (click)="changeTitle('Professors')">
<a class="nav-item nav-link ml-1" routerLink="/dashboard/professorManagement" routerLinkActive="active" (click)="changeTitle('Professors')">
<i class="fa fa-chalkboard-teacher"></i>
Professors
</a>
<a class="nav-item nav-link ml-1" routerLink="/blogs" routerLinkActive="active" (click)="changeTitle('Professors')">
<a class="nav-item nav-link ml-1" routerLink="/dashboard/blogs" routerLinkActive="active" (click)="changeTitle('Professors')">
<i class="fa fa-chalkboard-teacher"></i>
Blogs
</a>
<a class="nav-item nav-link ml-1" routerLink="/events" routerLinkActive="active" (click)="changeTitle('Professors')">
<a class="nav-item nav-link ml-1" routerLink="/dashboard/events" routerLinkActive="active" (click)="changeTitle('Professors')">
<i class="fa fa-chalkboard-teacher"></i>
Events
</a>
<a class="nav-item nav-link ml-3" routerLink="/settings" routerLinkActive="active" (click)="changeTitle('Settings')">
<a class="nav-item nav-link ml-3" routerLink="/dashboard/settings" routerLinkActive="active" (click)="changeTitle('Settings')">
<i class="fa fa-cogs"></i>
Settings
</a>
<a class="nav-item nav-link move-right mr-3" routerLink="/profile" routerLinkActive="active" (click)="changeTitle('Profile')">
<a class="nav-item nav-link move-right mr-3" routerLink="/dashboard/profile" routerLinkActive="active" (click)="changeTitle('Profile')">
Welcome, {{ loggedInUser.firstName }} {{ loggedInUser.lastName }}
<i class="fa fa-user"></i>
</a>
<a class="nav-item nav-link ml-1" (click)="logout()">
<!-- <a class="nav-item nav-link ml-1" (click)="logout()">
<i class="fa fa-sign-out-alt"></i>
Logout
</a>
</a> -->
</div>
</div>
</nav>

View File

@ -26,7 +26,7 @@ export class RegisterComponent implements OnInit, OnDestroy {
ngOnInit(): void {
if (this.authenticationService.isUserLoggedIn()) {
this.router.navigateByUrl("/user/management");
this.router.navigateByUrl("/dashboard/userManagement");
this.notificationService.notify(NotificationType.INFO, "You are already logged in");
}
}
@ -39,7 +39,7 @@ export class RegisterComponent implements OnInit, OnDestroy {
.subscribe(user => {
this.notificationService.notify(NotificationType.SUCCESS, `A new account was created for ${user.firstName}.
Please check your email for password to log in`);
this.router.navigateByUrl('/login');
this.router.navigateByUrl('/dashboard/login');
this.showLoading = false;
},
(errorResponse: HttpErrorResponse) => {

View File

@ -22,7 +22,7 @@
<i class="fa fa-users"></i>
Users
</a>
<a class="nav-item nav-link active ml-1" (click)="changeTitle('Professors')" [routerLink]="['/professor/management']" >
<a class="nav-item nav-link active ml-1" (click)="changeTitle('Professors')" [routerLink]="['/dashboard/professorManagement']" >
<i class="fa fa-users"></i>
Professors
</a>

View File

@ -236,7 +236,7 @@ export class UserComponent implements OnInit, OnDestroy {
onLogOut() {
this.authenticationService.logout();
this.router.navigate(['/login']);
this.router.navigate(['/dashboard/login']);
this.sendNotification(NotificationType.SUCCESS, 'You have been successfully logged out');
}

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { DataService } from './data.service';
describe('DataService', () => {
let service: DataService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(DataService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,389 @@
import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class DataService {
private url = "https://api.wrdpwd.com/soap/callWebService";
// private url =
// "https://clin.CMCVellore.ac.in/newconference/ConferencePay.asmx";
prod_cred = {
userName: "UMRCETS",
password: "us8FaGH5",
program: "TSURCME",
};
private test_url =
"https://clin.CMCVellore.ac.in/TestConference/ConferencePay.asmx";
test_cred = {
userName: "UMRESTC",
password: "zEVjHc9Y",
program: "TSURCME",
};
constructor(private httpClient: HttpClient) {}
// Method to send the SOAP request
sendSOAPRequestForStatus(formData: any): Observable<any> {
const headers = new HttpHeaders({
"Content-Type": "application/soap+xml; charset=utf-8",
SOAPAction: "http://www.cmch-vellore.edu/CONFONLINEPAYSTATUS",
});
const soapBody = this.generateSOAPBodyForStatus(this.prod_cred, formData);
console.log(soapBody);
return this.httpClient.post(this.url, soapBody, {
headers,
responseType: "text",
});
}
// Method to send the SOAP request
sendSOAPRequest(formData: any): Observable<any> {
const headers = new HttpHeaders({
"Content-Type": "application/soap+xml; charset=utf-8",
SOAPAction: "http://www.cmch-vellore.edu/NEWCONFONLINEPAYSAVE",
});
const soapBody = this.generateSOAPBody(this.prod_cred, formData);
console.log(soapBody);
return this.httpClient.post(this.url, soapBody, {
headers,
responseType: "text",
});
}
// Generate the SOAP body from form data
private generateSOAPBodyForStatus(userDetails: any, formData: any): string {
const soapXML = `
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:www="http://www.cmch-vellore.edu/">
<x:Header>
<www:UserDetails>
<www:userName>${userDetails.userName}</www:userName>
<www:password>${userDetails.password}</www:password>
<www:program>${userDetails.program}</www:program>
</www:UserDetails>
</x:Header>
<x:Body>
<www:CONFONLINEPAYSTATUS>
${this.generateFieldsXML(formData)}
</www:CONFONLINEPAYSTATUS>
</x:Body>
</x:Envelope>
`;
return soapXML;
}
// Generate the SOAP body from form data
private generateSOAPBody(userDetails: any, formData: any): string {
const soapXML = `
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:www="http://www.cmch-vellore.edu/">
<x:Header>
<www:UserDetails>
<www:userName>${userDetails.userName}</www:userName>
<www:password>${userDetails.password}</www:password>
<www:program>${userDetails.program}</www:program>
</www:UserDetails>
</x:Header>
<x:Body>
<www:NEWCONFONLINEPAYSAVE>
${this.generateFieldsXML(formData)}
</www:NEWCONFONLINEPAYSAVE>
</x:Body>
</x:Envelope>
`;
return soapXML;
}
// Generate the fields in SOAP XML format from form data
private generateFieldsXML(formData: any): string {
let fieldsXML = "";
// Iterate through form data and generate XML for each field
for (const key in formData) {
if (formData.hasOwnProperty(key)) {
fieldsXML += `<www:${key}>${formData[key]}</www:${key}>`;
}
}
return fieldsXML;
}
events = [
{
id: 1,
code: "TSURCME",
year: "2023",
subject: "CME on ",
title: " Advances in Chest Trauma Management ",
subTitle : "ACTraM 2023",
date: "13 & 14, October - 2023",
venue: [
{
title: "Symposium (Hybrid/ In person) ",
date: "13.10.2023",
address: "Conference Hall 7th floor, A-Block, CMC Vellore Ranipet Campus",
},
{
title: "Cadaveric Workshop ",
date: "14.10.2023",
address: "Antomy Dissection Hall, CMC Vellore Bagayam Campus",
info: "Limited seats & in person only",
},
],
highlights: [
"Keynote lectures by eminent national and international faculty",
"Sessions oriented towards understanding the intricacies of multidisciplinary care that is needed in the management of chest trauma patients. ",
"Challenging cases discussions ",
"Specific focus on intercostal drainage, minimally invasive chest surgery in trauma, thoracic rib fixation, pain relief medications in trauma and critical care management.",
"Hands-on cadaveric training on the basic principles of surgical rib fixation",
],
orgnisers: [
"Dr. Sukria Nayak - Organising Chairperson",
"Dr. Joses Dany James- Convener ",
"Dr. Vijayan P -Convener",
"Dr. Srujan Lam Sharma -Convener",
"Ms. Nithya.A- Manager",
"Mr. Prabhu - Manager",
],
fee: [
{ desc: "Online (ISTAC Members only) - ₹500", cost: 500 },
{ desc: "Symposium (In-person) - ₹1000", cost: 1000 },
{ desc: "Workshop (Only) - ₹3500", cost: 3500 },
{ desc: "Symposium & Workshop ₹4500", cost: 5310 },
{ desc: "* (+18% GST)", cost: 5310 },
],
phone: "04172 224627 ",
email: "traumasurg.academic@cmcvellore.ac.in",
isActive: true,
doctors: [
{
name: "Dr. Amit Gupta",
prof: "Professor",
at: "Division of Trauma Surgery JPNATC, AIIMS New Delhi",
id: 3,
image: "3.jpg",
},
{
name: "Dr. Subodh Kumar",
prof: "Professor",
at: "Division of Trauma Surgery, JPNATC, AIIMS New Delhi",
id: 2,
image: "2.jpg",
},
{
name: "Dr. Kajal Jain ",
prof: "Professor",
at: "Trauma Anaesthesia PGIMER, Chandigarh.",
id: 1,
image: "1.jpg",
},
{
name: "Dr. Krishnan Raghavendran ",
prof: "Professor",
at: " Division of Trauma and Acute Care Surgery, University Hospital, Ann Arbor Hospital Michigan",
id: 4,
image: "4.jpg",
},
{
name: "Dr. Balasubramoniam",
at: "Consultant Thoracic Surgeon, Yashoda group of Hospitals, Hyderabad",
id: 5,
image: "5.jpg",
},
{
name: "Dr. Niladri Banerjee",
prof: "Assistant Professor",
at: "Department of Surgery, AIIMS Jodhpur",
id: 8,
image: "8.jpg",
},
{
name: "Dr. Sukria Nayak",
prof: "Professor & Head",
at: " Department of Trauma Surgery, CMC Vellore",
id: 6,
image: "6.jpg",
},
{
name: "Dr. Ekta Rai",
prof: "Professor ",
at: "Department of Anesthesia,CMC Vellore",
id: 16,
image: "16.jpg",
},
{
name: "Dr.Madhu Andrew Philip",
at: "Prof & Head, Department of Cardiothoracic Surgery,CMC Vellore",
id: 17,
image: "17.jpg",
},
{
name: "Dr. Balasubramani",
prof: "Professor ",
at: "Department of Surgical ICU, CMC Vellore",
id: 18,
image: "18.jpg",
},
{
name: "Dr. Susheel Sudheesh",
prof: "Assistant Professor",
at: "Department of Anaesthesia, CMC Vellore",
id: 10,
image: "10.jpg",
},
{
name: "Dr. Srujan Lam Sharma",
prof: "Assistant Professor",
at: "Department of Trauma Surgery, CMC Vellore",
id: 12,
image: "12.jpg",
},
{
name: "Dr. Vinay M Rao ",
prof: "Associate Professor",
at: "Department of Cardiothoracic, Surgery CMC Vellore",
id: 7,
image: "7.jpg",
},
{
name: "Dr. Santhosh R Benjamin",
prof: "Associate Professor",
at: "Department of Cardiothoracic, Surgery,CMC Vellore",
id: 9,
image: "9.jpg",
},
{
name: "Dr. Kirthi Sathyakumar ",
prof: "Associate Professor",
at: "Emergency Radiology, CMC Vellore",
id: 11,
image: "11.jpg",
},
{
name: "Dr. Joses Dany James",
prof: "Assistant Professor",
at: "Department of Trauma Surgery, CMC Vellore",
id: 14,
image: "14.jpg",
},
{
name: "Dr. Vijayan P",
prof: "Associate Professor",
at: "Department of Trauma Surgery, CMC Vellore",
id: 13,
image: "13.jpg",
},
{
name: "Dr. Vignesh Kumar",
prof: "Associate Professor",
at: "Department of General Surgery, PIMS, Puducherry",
id: 15,
image: "15.jpg",
},
],
},
];
getAllConferenceData(): Observable<any> {
const url = "https://api.wrdpwd.com/soap/getAllConferenceData";
return this.httpClient.get(url);
}
// Create a method to send data via POST request
insertConferenceData(data: any): Observable<any> {
const url = "https://api.wrdpwd.com/soap/insertConferenceData";
// Define headers if needed (adjust as necessary)
const headers = new HttpHeaders({
"Content-Type": "application/json",
});
// Send the POST request
return this.httpClient.post(url, data, { headers });
}
// Create a method to send data via POST request
updateConferenceData(id, data: any): Observable<any> {
const url = "https://api.wrdpwd.com/soap/updateConferenceData/" + id;
// Define headers if needed (adjust as necessary)
const headers = new HttpHeaders({
"Content-Type": "application/json",
});
// Send the POST request
return this.httpClient.put(url, data, { headers });
}
partialUpdateConferenceData(id, data: any): Observable<any> {
const url = "https://api.wrdpwd.com/soap/partialUpdateConferenceData/" + id;
// Define headers if needed (adjust as necessary)
const headers = new HttpHeaders({
"Content-Type": "application/json",
});
// Send the POST request
return this.httpClient.patch(url, data, { headers });
}
getConferenceDataByRegno(id){
const url = "https://api.wrdpwd.com/soap/getConferenceDataByRegno/" + id;
// Define headers if needed (adjust as necessary)
const headers = new HttpHeaders({
"Content-Type": "application/json",
});
// Send the POST request
return this.httpClient.get(url, { headers });
}
getConferenceDataByPhone(id){
const url = "https://api.wrdpwd.com/soap/getConferenceDataByPhone/" + id;
// Define headers if needed (adjust as necessary)
const headers = new HttpHeaders({
"Content-Type": "application/json",
});
// Send the POST request
return this.httpClient.get(url, { headers });
}
// Create a method to send data via POST request
deleteConferenceData(id): Observable<any> {
const url = "https://api.wrdpwd.com/soap/deleteConferenceData/" + id;
// Define headers if needed (adjust as necessary)
const headers = new HttpHeaders({
"Content-Type": "application/json",
});
// Send the POST request
return this.httpClient.delete(url, { headers });
}
}
export class PaymentInfo {
Registration: string;
Transid: string;
ResultCode: string;
Result: string;
URL: string;
}

View File

@ -28,7 +28,7 @@ export class AuthenticationGuard implements CanActivate {
if (this.authenticationService.isUserLoggedIn())
return true;
else {
this.router.navigate(['/login']);
this.router.navigate(['/dashboard/login']);
this.notificationService.notify(NotificationType.ERROR, `You need to log in to access this page`);

View File

@ -0,0 +1,67 @@
<div class="container mt-4">
<h2 class="mb-4">Detail Info</h2>
<div *ngIf="rowData" class="card">
<div class="card-body">
<h5 class="-title">Candidate Information</h5>
<!-- Display the labels based on their corresponding inputcaptionX values -->
<!-- Add the remaining fields here using the same pattern -->
<p class="card-text"><strong>ID:</strong> {{ rowData.id || "-NA-"}}</p>
<p class="card-text"><strong>Conference Code:</strong> {{ rowData.conferencecode || "-NA-"}}</p>
<p class="card-text"><strong>Conference Year:</strong> {{ rowData.conferenceyear || "-NA-"}}</p>
<p class="card-text"><strong>Bank Name:</strong> {{ rowData.bankname || "-NA-"}}</p>
<p class="card-text"><strong>Remote IP:</strong> {{ rowData.remoteip || "-NA-"}}</p>
<p class="card-text"><strong>Registration Number:</strong> {{ rowData.regno || "-NA-"}}</p>
<p class="card-text"><strong>Candidate Name:</strong> {{ rowData.candidatename || "-NA-"}}</p>
<p class="card-text"><strong>Name in Receipt:</strong> {{ rowData.nameinreceipt || "-NA-"}}</p>
<p class="card-text"><strong>Address 1:</strong> {{ rowData.address1 || "-NA-"}}</p>
<p class="card-text"><strong>Address 2:</strong> {{ rowData.address2 || "-NA-"}}</p>
<p class="card-text"><strong>Country:</strong> {{ rowData.country || "-NA-"}}</p>
<p class="card-text"><strong>Pincode:</strong> {{ rowData.pincode || "-NA-"}}</p>
<p class="card-text"><strong>Phone:</strong> {{ rowData.phone || "-NA-"}}</p>
<p class="card-text"><strong>Mobile:</strong> {{ rowData.mobile || "-NA-"}}</p>
<p class="card-text"><strong>Email:</strong> {{ rowData.email || "-NA-"}}</p>
<p class="card-text"><strong>Food Type:</strong> {{ rowData.foodtype || "-NA-"}}</p>
<p class="card-text"><strong>Participant Type:</strong> {{ rowData.participanttype || "-NA-"}}</p>
<p class="card-text"><strong>Practice Type:</strong> {{ rowData.practicetype || "-NA-"}}</p>
<p class="card-text"><strong>Accompany Members:</strong> {{ rowData.accompanymembers || "-NA-"}}</p>
<p class="card-text"><strong>External or CMC Staff: </strong>: {{ rowData.inputvalue5 || "-NA-"}}</p>
<p class="card-text"><strong>Payment Amount:</strong> {{ rowData.paymentamount || "-NA-"}}</p>
<p class="card-text"><strong>Has GST:</strong> {{ rowData.hasgst || "-NA-"}}</p>
<p class="card-text"><strong>GST Number:</strong> {{ rowData.gstnumber || "-NA-"}}</p>
<p class="card-text"><strong>GST Mobile Number:</strong> {{ rowData.gstmobileno || "-NA-"}}</p>
<p class="card-text"><strong>GST Email ID:</strong> {{ rowData.gstemailid || "-NA-"}}</p>
<p class="card-text"><strong>To Wards:</strong> {{ rowData.toWards || "-NA-"}}</p>
<p class="card-text"><strong>Allow 80G:</strong> {{ rowData.allow80G || "-NA-"}}</p>
<p class="card-text"><strong>Pan Card Number:</strong> {{ rowData.panCardNo || "-NA-"}}</p>
<p class="card-text"><strong>GST Registration:</strong> {{ rowData.gstreg || "-NA-"}}</p>
<!-- Add any additional fields as needed -->
<p class="card-text"><strong>CMC MISSION:</strong> {{ rowData.city || "-NA-"}}</p>
<p class="card-text"><strong>MISSION ID:</strong> {{ rowData.state || "-NA-"}}</p>
<p class="card-text"><strong>designation: </strong>: {{ rowData.inputvalue1 || "-NA-"}}</p>
<p class="card-text"><strong>placeOfWork: </strong>: {{ rowData.inputcaption2 || "-NA-"}}</p>
<p class="card-text"><strong>medicalCollegeName: </strong>: {{ rowData.inputvalue2 || "-NA-"}}</p>
<p class="card-text"><strong>hospitalName: </strong>: {{ rowData.inputcaption3 || "-NA-"}}</p>
<p class="card-text"><strong>istacMember: </strong>: {{ rowData.inputvalue3 || "-NA-"}}</p>
<p class="card-text"><strong>istacMemberID: </strong>: {{ rowData.inputcaption4 || "-NA-"}}</p>
<p class="card-text"><strong>registrationType: </strong>: {{ rowData.inputvalue4 || "-NA-"}}</p>
<p class="card-text"><strong>submitCase: </strong>: {{ rowData.inputcaption5 || "-NA-"}}</p>
<p class="card-text"><strong>isPaymentDone: </strong>: {{ rowData.inputcaption1 || "-NA-"}}</p>
<p class="card-text"><strong>Response Transaction ID:</strong> {{ rowData.responseTransid || "-NA-"}}</p>
<p class="card-text"><strong>Response Result Code:</strong> {{ rowData.responseResultCode || "-NA-"}}</p>
<p class="card-text"><strong>Response Result:</strong> {{ rowData.responseResult || "-NA-"}}</p>
<p class="card-text"><strong>Response URL:</strong> {{ rowData.responseURL || "-NA-"}}</p>
</div>
</div>
</div>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CandidateDetailsComponent } from './candidate-details.component';
describe('CandidateDetailsComponent', () => {
let component: CandidateDetailsComponent;
let fixture: ComponentFixture<CandidateDetailsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ CandidateDetailsComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(CandidateDetailsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,26 @@
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-candidate-details',
templateUrl: './candidate-details.component.html',
styleUrls: ['./candidate-details.component.scss']
})
export class CandidateDetailsComponent implements OnInit {
rowData: any; // Data for the selected row
constructor(private route: ActivatedRoute) { }
ngOnInit() {
// Retrieve the data object from the route's state
this.route.paramMap.subscribe(params => {
const dataString = params.get('data');
if (dataString) {
this.rowData = JSON.parse(dataString);
}
});
}
}

View File

@ -0,0 +1,147 @@
<div class="row p-3">
<div class="col-6">
<div class="card mb-3">
<div class="card-header">Registration Info</div>
<div class="card-body">
<form [formGroup]="detailForm" (ngSubmit)="detailFormSubmit()">
<div class="form-group">
<label for="phone">Mobile Number</label>
<input
type="text"
class="form-control"
id="phone"
formControlName="phone"
/>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
<div class="card" *ngIf="obj.id">
<div class="card-body">
<h5 class="card-title">Conference Information</h5>
<hr />
<table class="table">
<tbody>
<tr>
<th>ID</th>
<td>{{ obj.id }}</td>
</tr>
<tr>
<th>Conference Code</th>
<td>{{ obj.conferencecode }}</td>
</tr>
<tr>
<th>Conference Year</th>
<td>{{ obj.conferenceyear }}</td>
</tr>
<tr>
<th>Bank Name</th>
<td>{{ obj.bankname }}</td>
</tr>
<tr>
<th>Registration Number</th>
<td>{{ obj.regno }}</td>
</tr>
<tr>
<th>Response Transaction ID</th>
<td>{{ obj.responseTransid }}</td>
</tr>
<tr>
<th>Name </th>
<td>{{ obj.nameinreceipt }}</td>
</tr>
<tr>
<th>Address</th>
<td>{{ obj.address1 }}</td>
</tr>
<tr>
<th>Phone</th>
<td>{{ obj.phone }}</td>
</tr>
<tr>
<th>Payment Status</th>
<td>{{ obj.inputcaption1 }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-6">
<div class="card">
<div class="card-header">Transaction Status</div>
<div class="card-body">
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="regno">Reg No</label>
<input
type="text"
class="form-control"
id="regno"
formControlName="regno"
/>
</div>
<div class="form-group">
<label for="transid">Transaction ID</label>
<input
type="text"
class="form-control"
id="transid"
formControlName="transid"
/>
</div>
<div class="form-group">
<label for="conference">Conference</label>
<input
type="text"
class="form-control"
id="conference"
formControlName="conference"
/>
</div>
<div class="form-group">
<label for="confyear">Conference Year</label>
<input
type="text"
class="form-control"
id="confyear"
formControlName="confyear"
/>
</div>
<div class="form-group">
<label for="bankname">Bank Name</label>
<input
type="text"
class="form-control"
id="bankname"
formControlName="bankname"
/>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
<div class="card mt-3" *ngIf="status.Transid">
<div class="card-body">
<h5 class="card-title">Transaction Details</h5>
<hr />
<table class="table">
<tbody>
<!-- <tr>
<th>Property</th>
<th>Value</th>
</tr> -->
<tr *ngFor="let property of status | keyvalue">
<th>{{ property.key }}</th>
<td>{{ property.value }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CheckStatusComponent } from './check-status.component';
describe('CheckStatusComponent', () => {
let component: CheckStatusComponent;
let fixture: ComponentFixture<CheckStatusComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ CheckStatusComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(CheckStatusComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,69 @@
import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { DataService } from "src/app/data.service";
import { XmlParserService } from "src/app/xml-parser.service";
@Component({
selector: "app-check-status",
templateUrl: "./check-status.component.html",
styleUrls: ["./check-status.component.scss"],
})
export class CheckStatusComponent implements OnInit {
form: FormGroup;
detailForm: FormGroup;
constructor(
private fb: FormBuilder,
private dataService: DataService,
private parser: XmlParserService
) {}
ngOnInit() {
this.form = this.fb.group({
regno: ["", Validators.required],
transid: ["", Validators.required],
conference: ["", Validators.required],
confyear: ["", Validators.required],
bankname: ["", Validators.required],
});
this.detailForm = this.fb.group({
phone: ["", Validators.required],
});
}
status: any = {};
onSubmit() {
if (this.form.valid) {
// Handle form submission here
console.log(this.form.value);
this.dataService.sendSOAPRequestForStatus(this.form.value).subscribe(
(res) => {
console.log(res);
this.status = this.parser.parseXmlForStatus(res);
console.log(this.status);
},
(error) => alert("something went wrong " + error)
);
} else {
alert("all field values are required");
}
}
obj: any = {};
detailFormSubmit() {
if (this.detailForm.valid) {
// Handle form submission here
console.log(this.form.value);
this.dataService
.getConferenceDataByPhone(this.detailForm.get("phone").value)
.subscribe(
(res) => {
this.obj = res;
},
(error) => alert("something went wrong " + error)
);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IndexComponent } from './index.component';
describe('IndexComponent', () => {
let component: IndexComponent;
let fixture: ComponentFixture<IndexComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ IndexComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(IndexComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,37 @@
import { Component, OnInit } from '@angular/core';
import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { isPlatformBrowser } from '@angular/common';
@Component({
selector: 'app-index',
templateUrl: './index.component.html',
styleUrls: ['./index.component.css']
})
export class IndexComponent implements OnInit {
ngOnInit(): void {
this.injectTags()
}
private filePath = '/src/extrascripts.html'; // Adjust the path as needed
constructor(private http: HttpClient, @Inject(PLATFORM_ID) private platformId: Object) {}
injectTags(): void {
if (isPlatformBrowser(this.platformId)) {
this.http.get(this.filePath, { responseType: 'text' }).subscribe(data => {
const head = document.head || document.getElementsByTagName('head')[0];
const tempDiv = document.createElement('div');
tempDiv.innerHTML = data;
Array.from(tempDiv.childNodes).forEach(child => head.appendChild(child));
});
}
}
}

View File

@ -0,0 +1,113 @@
<!-- STRAT NAVBAR -->
<nav class="navbar navbar-expand-lg fixed-top navbar-custom sticky sticky-dark" id="navbar"
(window:scroll)="windowScroll()">
<div class="container">
<a class="navbar-brand" href="#">CMC Vellore</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse"
aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation" (click)="toggleMenu()">
<span class="ti-menu"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mx-auto" id="navbar-navlist">
<li class="nav-item" [ngClass]="{'active':currentSection === 'home'}">
<a [ngxScrollTo]="'#home'" class="nav-link" href="javascript: void(0);">Home</a>
</li>
<li class="nav-item" [ngClass]="{'active':currentSection === 'features'}">
<a [ngxScrollTo]="'#features'" class="nav-link" href="javascript: void(0);">Facility</a>
</li>
<li class="nav-item" [ngClass]="{'active':currentSection === 'team'}">
<a [ngxScrollTo]="'#team'" class="nav-link" href="javascript: void(0);">Faculties</a>
</li>
<li class="nav-item" [ngClass]="{'active':currentSection === 'pricing'}">
<a [ngxScrollTo]="'#pricing'" class="nav-link" href="javascript: void(0);">Events</a>
</li>
<!-- <li class="nav-item" [ngClass]="{'active':currentSection === 'testi'}">
<a [ngxScrollTo]="'#testi'" class="nav-link" href="javascript: void(0);">Client</a>
</li> -->
<li class="nav-item" [ngClass]="{'active':currentSection === 'faq'}">
<a [ngxScrollTo]="'#faq'" class="nav-link" href="javascript: void(0);">our Focus</a>
</li>
<li class="nav-item" [ngClass]="{'active':currentSection === 'services'}">
<a [ngxScrollTo]="'#services'" class="nav-link" href="javascript: void(0);">About us</a>
</li>
<li class="nav-item" [ngClass]="{'active':currentSection === 'contact'}">
<a [ngxScrollTo]="'#contact'" class="nav-link" href="javascript: void(0);">Contact</a>
</li>
<!--
<li class="nav-item" >
<a routerLink="/check-status" class="nav-link" href="javascript: void(0);">Registration status</a>
</li> -->
</ul>
<div>
<ul class="text-right list-unstyled list-inline mb-0 nav-social">
<li class="list-inline-item text-white nav-number"><i class="ti-mobile"></i> <span> 04172 224627 / 224626
</span></li>
<!-- <li class="list-inline-item"><a href="" class="facebook"><i class="ti-facebook"></i></a></li> -->
</ul>
</div>
</div>
</div>
</nav>
<!-- END NAVBAR -->
<div appScrollspy [spiedTags]="['SECTION']" (sectionChange)="onSectionChange($event)">
<!-- START HOME -->
<section class="back-slide" id="home">
<img name="silde" class="slide-img" id="isSlideImage" src="assets/images/cmc/drapt2.jpeg">
<div class="bg-overlay"></div>
<div class="home-center">
<div class="home-desc-center">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-10">
<div class="text-center">
<h1 class="text-white home-title mb-0">Christian Medical College, Vellore</h1>
<p class="text-white home-subtitle-center home-subtitle mt-4 mb-0 mx-auto">The Christian Medical College, Vellore, seeks to be a witness to the healing ministry of Christ, through excellence in education, service and research.</p>
<!-- <div class="text-center search-form mt-4">
<form action="#">
<input type="text" placeholder="Email">
<button type="submit" class="btn btn-primary">SubCribe</button>
</form>
</div> -->
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- END HOME -->
<app-features></app-features>
<app-team></app-team>
<app-pricing></app-pricing>
<!-- <app-client></app-client> -->
<app-faq></app-faq>
<app-services></app-services>
<app-contact></app-contact>
<app-footer></app-footer>
<!-- <app-switcher></app-switcher> -->
</div>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Index6Component } from './index6.component';
describe('Index6Component', () => {
let component: Index6Component;
let fixture: ComponentFixture<Index6Component>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ Index6Component ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(Index6Component);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,109 @@
import { Component, OnInit } from '@angular/core';
import { StudentService } from 'src/app/student.service';
@Component({
selector: 'app-index6',
templateUrl: './index6.component.html',
styleUrls: ['./index6.component.scss']
})
/**
* Index-6 component
*/
export class Index6Component implements OnInit {
constructor(private studentService : StudentService) { }
currentSection = 'home';
students
student
ngOnInit() {
// this.students = this.studentService.getAllStudents();
// console.log("students : ",this.students);
// this.student = this.studentService.insertStudent();
// console.log("student : ",this.student);
// this.studentService.makeHttpRequest().subscribe(
// (response) => {
// // Handle the response here
// console.log(response);
// },
// (error) => {
// // Handle errors here
// console.error(error);
// }
// );
document.addEventListener("DOMContentLoaded", () => {
let i = 1;
setInterval(() => {
const slideImage = document.querySelector("#isSlideImage") as HTMLImageElement; // Cast to HTMLImageElement
if (!slideImage) {
return; // Exit if the element is not found
}
if (i === 1) {
slideImage.src = 'assets/images/cmc/drapt2.jpeg';
} else if (i === 2) {
slideImage.src = 'assets/images/cmc/CMCH_Vellore.jpeg';
} else {
slideImage.src = 'assets/images/cmc/ranipet-Kannigapuram-2022-06-15-main-entrance-signsWA-1.jpeg';
}
if (i >= 3) {
i = 0;
}
i++;
}, 2500);
});
// let i = 1;
// setInterval(() => {
// if (i === 1) { (<HTMLImageElement>document.querySelector("#isSlideImage")).src = 'assets/images/cmc/drapt2.jpeg'; }
// else if (i === 2) { (<HTMLImageElement>document.querySelector("#isSlideImage")).src = 'assets/images/cmc/CMCH_Vellore.jpeg'; }
// else { (<HTMLImageElement>document.querySelector("#isSlideImage")).src = 'assets/images/cmc/ranipet-Kannigapuram-2022-06-15-main-entrance-signsWA-1.jpeg'; }
// if (i >= 3) { i = 0; }
// i++;
// }, 2500);
}
/**
* Window scroll method
*/
// tslint:disable-next-line: typedef
windowScroll() {
const navbar = document.getElementById('navbar');
if (document.body.scrollTop > 40 || document.documentElement.scrollTop > 40) {
navbar.style.backgroundColor = '#1a1a1a';
navbar.style.padding = '15px 0px';
}
else {
navbar.style.backgroundColor = '';
navbar.style.padding = '20px';
}
}
/**
* Toggle navbar
*/
toggleMenu() {
document.getElementById('navbarCollapse').classList.toggle('show');
}
/**
* Section changed method
* @param sectionId specify the current sectionID
*/
onSectionChange(sectionId: string) {
this.currentSection = sectionId;
}
}

View File

@ -0,0 +1,59 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { Index6Component } from './index6/index6.component';
import { PasswordForgetComponent } from './password-forget/password-forget.component';
import { SignupComponent } from './signup/signup.component';
import { RegisterComponent } from './register/register.component';
import { RegistrationStatusComponent } from './registration-status/registration-status.component';
import { RegistedListComponent } from './registed-list/registed-list.component';
import { CandidateDetailsComponent } from './candidate-details/candidate-details.component';
import { CheckStatusComponent } from './check-status/check-status.component';
const routes: Routes = [
{
path: 'index',
component: Index6Component
},
{
path: 'registrationStatus',
component: RegistrationStatusComponent
},
{
path: 'check-status',
component: CheckStatusComponent
},
{
path: 'admin',
component: RegistedListComponent
},
{ path: 'detail', component: CandidateDetailsComponent },
{
path: 'password_forget',
component: PasswordForgetComponent
},
{
path: 'signup',
component: SignupComponent
},
{
path: 'register/:id',
component: RegisterComponent
},
{
path: '',
redirectTo: 'index',
pathMatch: 'full'
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class PagesRoutingModule { }

View File

@ -0,0 +1,46 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to';
import { NgxTypedJsModule } from 'ngx-typed-js';
// import { NgParticlesModule } from 'ng-particles';
import { CarouselModule } from 'ngx-owl-carousel-o';
import { PagesRoutingModule } from './pages-routing.module'
import { SharedModule } from '../shared/shared.module';
import { Index6Component } from './index6/index6.component';
import { PasswordForgetComponent } from './password-forget/password-forget.component';
import { SignupComponent } from './signup/signup.component';
import { RegisterComponent } from './register/register.component';
import { RegistrationStatusComponent } from './registration-status/registration-status.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { RegistedListComponent } from './registed-list/registed-list.component';
import { CandidateDetailsComponent } from './candidate-details/candidate-details.component';
import { CheckStatusComponent } from './check-status/check-status.component';
import { BrowserModule } from '@angular/platform-browser';
import { IndexComponent } from './index/index.component';
@NgModule({
declarations: [Index6Component, PasswordForgetComponent, SignupComponent,RegisterComponent, RegistrationStatusComponent,RegistedListComponent, CandidateDetailsComponent, CheckStatusComponent, IndexComponent],
imports: [
// BrowserModule,
CommonModule,
SharedModule,
PagesRoutingModule,
ScrollToModule.forRoot(),
NgxTypedJsModule,
// NgParticlesModule,
CarouselModule,
ReactiveFormsModule,
// HttpClientModule,
FormsModule
]
})
export class PagesModule { }

View File

@ -0,0 +1,28 @@
<section class="bg-login d-flex align-items-center">
<div class="container">
<div class="row justify-content-center mt-4">
<div class="col-lg-4">
<div class="bg-white p-4 mt-5 rounded">
<div class="text-center">
<h4 class="fw-bold mb-3">Globing</h4>
</div>
<h6 class="text-center text-muted fw-normal forgot-pass-txt">Enter your email address
and we'll send you an email with instructions to reset your password.</h6>
<form class="login-form">
<div class="row">
<div class="col-lg-12 mt-3">
<input type="email" class="form-control" placeholder="Email" required="">
</div>
<div class="col-lg-12 mt-4 mb-2">
<button class="btn btn-primary w-100">Reset your Password</button>
</div>
</div>
</form>
</div>
<div class="text-center mt-3">
<p><small class="text-white me-2">Already have account?</small> <a routerLink="/login" class="text-white fw-bold">Sign in</a></p>
</div>
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PasswordForgetComponent } from './password-forget.component';
describe('PasswordForgetComponent', () => {
let component: PasswordForgetComponent;
let fixture: ComponentFixture<PasswordForgetComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PasswordForgetComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PasswordForgetComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-password-forget',
templateUrl: './password-forget.component.html',
styleUrls: ['./password-forget.component.scss']
})
export class PasswordForgetComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@ -0,0 +1,123 @@
<div class="container mt-3" *ngIf="!showTable">
<!-- Secret key input form -->
<div class="form-group">
<label for="secretKey">Enter Secret Key:</label>
<input
class="form-control"
type="password"
id="secretKey"
[(ngModel)]="secretKey"
/>
<button (click)="checkSecretKey()">Submit</button>
</div>
</div>
<!-- Table - Display only if showTable is true -->
<div class="row p-2" *ngIf="showTable">
<button class="btn btn-sm btn-success float-end" (click)="exportToExcel()">
Export to Excel
</button>
<div class="table-responsive">
<table class="table" id="myTable">
<thead class="thead-dark">
<tr>
<th>ID</th>
<th>Registration Number</th>
<th>Transaction ID</th>
<th>Name in Receipt</th>
<!-- <th>Conference Code</th> -->
<th>Bank Name</th>
<th>Phone</th>
<th>Designation</th>
<th>Place of work</th>
<th>Name of the hospital, college</th>
<th>ISTAC member</th>
<th>CMC Mission</th>
<th>External or CMC staff</th>
<th>registration type</th>
<th>submit case</th>
<th>Email</th>
<th>Payment Amount</th>
<th>Payment Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let payment of payments">
<tr>
<td>{{ payment.id || "NA"}}</td>
<td>{{ payment.regno || "NA"}}</td>
<td>{{ payment.responseTransid || payment.Transid || "NA"}}</td>
<td>{{ payment.nameinreceipt || "NA"}}</td>
<!-- <td>{{ payment.conferencecode || "NA"}}</td> -->
<td>{{ payment.bankname || "NA"}}</td>
<td>{{ payment.phone || "NA"}}</td>
<td>{{ payment.inputvalue1 || "NA"}}</td>
<td>{{ payment.inputcaption2 || "NA"}}</td>
<td>
<span *ngIf=" payment.inputcaption3">{{ payment.inputcaption3 }}</span
><span *ngIf=" payment.inputvalue2">{{ payment.inputvalue2 }}</span>
</td>
<td>{{ payment.inputvalue3 || "NA"}}</td>
<td>{{ payment.city || "NA"}}</td>
<td>{{payment.inputvalue5 == 'No Error' ? "NA" : payment.inputvalue5}}</td>
<td>{{payment.inputvalue4 || "NA"}}</td>
<td>{{ payment.inputcaption5 || "NA"}}</td>
<td>{{ payment.email || "NA"}}</td>
<td>{{ payment.paymentamount || "NA"}}</td>
<td>
<span
[ngClass]="{
success: payment.inputcaption1 === 'Y',
failed: payment.inputcaption1 === 'F',
unknown:
payment.inputcaption1 !== 'Y' &&
payment.inputcaption1 !== 'F'
}"
>
{{
payment.inputcaption1 === "Y"
? "Success"
: payment.inputcaption1 === "F"
? "Failed"
: "Unknown"
}}
</span>
</td>
<td>
<!-- <button class="mx-2" (click)="delete(payment.id)">
<i class="ti-trash"></i>
</button> -->
<button (click)="viewDetail(payment)">
<i class="ti-eye"></i>
</button>
</td>
</tr>
</ng-container>
</tbody>
</table>
</div>
</div>

View File

@ -0,0 +1,14 @@
/* CSS file (your-component.component.css) */
.success {
color: green;
}
.failed {
color: red;
}
.unknown {
color: gray;
}

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RegistedListComponent } from './registed-list.component';
describe('RegistedListComponent', () => {
let component: RegistedListComponent;
let fixture: ComponentFixture<RegistedListComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ RegistedListComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(RegistedListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,87 @@
import { Component, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { DataService } from "src/app/data.service";
import * as XLSX from "xlsx";
// import * as FileSaver from "file-saver";
@Component({
selector: "app-registed-list",
templateUrl: "./registed-list.component.html",
styleUrls: ["./registed-list.component.scss"],
})
export class RegistedListComponent implements OnInit {
secretKey: string = ""; // Property to store the secret key
showTable: boolean = false; // Flag to determine if the table should be displayed
payments = [
// Add more payment objects here
];
constructor(private dataService: DataService, private router: Router) {}
exportToExcel() {
const element = document.getElementById("myTable"); // Replace 'myTable' with the ID of your HTML table
const ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(element);
const wb: XLSX.WorkBook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
const excelBuffer: any = XLSX.write(wb, {
bookType: "xlsx",
type: "array",
});
const blob = new Blob([excelBuffer], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
});
// FileSaver.saveAs(blob, "myTable.xlsx"); // Specify the desired file name
}
viewDetail(rowData: any) {
this.router.navigate(["detail", { data: JSON.stringify(rowData) }]);
}
delete(id) {
if (this.confirmData())
this.dataService.deleteConferenceData(id).subscribe((res) => {
console.log(res);
this.getList()
});
}
confirmData(): boolean {
return confirm("Are you sure you want to delete?");
}
ngOnInit(): void {
this.getList()
}
getList(){
this.payments = []
this.dataService.getAllConferenceData().subscribe((res) => {
this.payments = res;
});
}
checkSecretKey() {
// Replace 'yourSecretKey' with the actual correct secret key
if (this.secretKey === "975312") {
this.showTable = true; // Show the table if the key is correct
} else {
this.showTable = false; // Hide the table if the key is incorrect
// Optionally, you can display an error message or take other actions.
}
}
updateStatus() {
for (const obj of this.payments) {
// Call the service method to update the object's status
// this.dataService.updateObjectStatus(obj).subscribe(
// (response: any) => {
// console.log(response)
// },
// (error) => {
// console.error('Error updating object status:', error);
// }
// );
}
}
}

View File

@ -0,0 +1,959 @@
<div *ngIf="paymentInfo.ResultCode != '0'" class="row mt-2">
<div class="col-lg">
<div class="container">
<div class="card">
<div class="card-body">
<h4 class="card-title">Registration Form</h4>
<hr />
<br />
<form [formGroup]="registrationForm" (ngSubmit)="onSubmit()">
<!-- Conference Code -->
<div class="form-group mb-3">
<label class="text-primary" for="conferencecode"
>Conference Code: *</label
>
<input
class="form-control"
type="text"
id="conferencecode"
formControlName="conferencecode"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('conferencecode').hasError('required')
"
class="error-message"
>This field is required.</small
>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('conferencecode').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Conference Year -->
<div class="form-group mb-3">
<label class="text-primary" for="conferenceyear"
>Conference Year: *</label
>
<input
class="form-control"
type="text"
id="conferenceyear"
formControlName="conferenceyear"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('conferenceyear').hasError('required')
"
class="error-message"
>This field is required.</small
>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('conferenceyear').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Client IP Address (Remote IP Address) -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="remoteip">Client IP Address:</label>
<input
class="form-control"
type="text"
id="remoteip"
formControlName="remoteip"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('remoteip').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Registration Number -->
<div class="form-group mb-3">
<label class="text-primary" for="regno"
>Registration Number: *</label
>
<input
class="form-control"
type="text"
id="regno"
formControlName="regno"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('regno').hasError('required')"
class="error-message"
>This field is required.</small
>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('regno').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Payee Name (Candidate Name) -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label class="text-primary" for="candidatename"
>Payee Name: *</label
>
<input
class="form-control"
type="text"
id="candidatename"
formControlName="candidatename"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('candidatename').hasError('required')
"
class="error-message"
>This field is required.</small
>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('candidatename').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Name to be printed in Receipt -->
<div class="form-group mb-3">
<label class="text-primary" for="nameinreceipt"
>Name to be printed on the certificate: *</label
>
<input
class="form-control"
type="text"
id="nameinreceipt"
formControlName="nameinreceipt"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('nameinreceipt').hasError('required')
"
class="error-message"
>This field is required.</small
>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('nameinreceipt').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<div class="form-group mb-3">
<label for="designation">Designation:</label>
<select
class="form-control"
id="designation"
formControlName="designation"
>
<option value="Undergraduate">Undergraduate</option>
<option value="Postgraduate">Postgraduate</option>
<option value="Consultant">Consultant</option>
</select>
</div>
<div class="form-group mb-3">
<label for="placeOfWork">Present place of work:</label>
<select
class="form-control"
id="placeOfWork"
formControlName="placeOfWork"
>
<option value="None">None</option>
<option value="PrivatePractice">Private practice</option>
<option value="MedicalCollege">Medical College</option>
<option value="Hospital">Hospital</option>
</select>
</div>
<!-- Conditional input field for Medical College -->
<div
class="form-group mb-3"
*ngIf="
registrationForm.get('placeOfWork').value === 'MedicalCollege'
"
>
<label for="medicalCollegeName">Name of Medical College:</label>
<input
class="form-control"
type="text"
id="medicalCollegeName"
formControlName="medicalCollegeName"
/>
</div>
<!-- Conditional input field for Hospital -->
<div
class="form-group mb-3"
*ngIf="registrationForm.get('placeOfWork').value === 'Hospital'"
>
<label for="hospitalName">Name of Hospital:</label>
<input
class="form-control"
type="text"
id="hospitalName"
formControlName="hospitalName"
/>
</div>
<!-- Address Line 1 -->
<div class="form-group mb-3">
<label for="address1">Address </label>
<textarea
class="form-control"
type="text"
id="address1"
formControlName="address1"
rows="3"
>
</textarea>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('address1').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Address Line 2 -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="address2">Address Line 2:</label>
<input
class="form-control"
type="text"
id="address2"
formControlName="address2"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('address2').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- City -->
<!-- <div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="city">City:</label>
<input
class="form-control"
type="text"
id="city"
formControlName="city"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('city').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div> -->
<!-- State -->
<!-- <div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="state">State:</label>
<input
class="form-control"
type="text"
id="state"
formControlName="state"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('state').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div> -->
<!-- Country -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="country">Country:</label>
<input
class="form-control"
type="text"
id="country"
formControlName="country"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('country').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Pincode -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="pincode">Pincode:</label>
<input
class="form-control"
type="text"
id="pincode"
formControlName="pincode"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('pincode').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Landline Number (Phone) -->
<div class="form-group mb-3" >
<label class="text-primary" for="phone">Mobile Number:</label>
<input
class="form-control"
type="text"
id="phone"
formControlName="phone"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('phone').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
<small class="form-text text-muted" *ngIf="registrationForm.get('phone').hasError('required')"
class="error-message">This field is required.</small>
</div>
<!-- Mobile Number -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="mobile">Mobile Number:</label>
<input
class="form-control"
type="text"
id="mobile"
formControlName="mobile"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('mobile').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Email ID -->
<div class="form-group mb-3">
<label for="email">Email ID:</label>
<input
class="form-control"
type="text"
id="email"
formControlName="email"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('email').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Food Type -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="foodtype">Food Type:</label>
<select
class="form-control"
id="foodtype"
formControlName="foodtype"
>
<option value="">Select Food Type</option>
<option value="V">V - Veg</option>
<option value="NV">NV - Non-Veg</option>
</select>
</div>
<!-- Participant Type -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="participanttype">Participant Type:</label>
<input
class="form-control"
type="text"
id="participanttype"
formControlName="participanttype"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('participanttype').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Practice Type -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="practicetype">Practice Type:</label>
<input
class="form-control"
type="text"
id="practicetype"
formControlName="practicetype"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('practicetype').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Accompany Persons -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="accompanymembers">Accompany Persons:</label>
<input
class="form-control"
type="text"
id="accompanymembers"
formControlName="accompanymembers"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('accompanymembers').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Registration Fees (Payment Amount) -->
<!-- <div class="form-group mb-3">
<label class="text-primary" for="paymentamount">Registration Fees: *</label>
<select class="form-control" id="paymentamount" formControlName="paymentamount">
<option *ngFor="let option of event.fee" [value]="option.cost">
{{ option.desc }} - <span class="text-primary"> (Rs. {{ option.cost }}) </span>
</option>
</select>
<small class="form-text text-muted" *ngIf="registrationForm.get('paymentamount').hasError('required')"
class="error-message">This field is required.</small>
</div> -->
<div class="card p-2 mb-3">
<div class="form-group mb-3">
<label>ISTAC Members:</label>
<div class="form-check">
<input
class="form-check-input"
type="radio"
id="istacMemberYes"
value="Yes"
formControlName="istacMember"
/>
<label class="form-check-label"> Yes </label>
</div>
<div class="form-check">
<input
class="form-check-input"
type="radio"
id="istacMemberNo"
value="No"
formControlName="istacMember"
/>
<label class="form-check-label"> No </label>
</div>
</div>
</div>
<div
class="form-group mb-3"
*ngIf="registrationForm.get('istacMember').value === 'Yes'"
>
<label for="istacMemberID">ISTAC Member ID:</label>
<input
type="text"
class="form-control"
id="istacMemberID"
formControlName="istacMemberID"
/>
</div>
<div class="card p-2 mb-3">
<div class="form-group mb-3">
<label> CMC Mission:</label>
<div class="form-check">
<input
class="form-check-input"
type="radio"
id="cityYes"
value="Yes"
formControlName="city"
/>
<label class="form-check-label"> Yes </label>
</div>
<div class="form-check">
<input
class="form-check-input"
type="radio"
id="cityNo"
value="No"
formControlName="city"
/>
<label class="form-check-label"> No </label>
</div>
</div>
</div>
<div
class="form-group mb-3"
*ngIf="registrationForm.get('city').value === 'Yes'"
>
<label for="stateID">CMC Mission ID:</label>
<input
type="text"
class="form-control"
id="stateID"
formControlName="state"
/>
</div>
<!-- <div class="form-group mb-3">
<label for="paymentamount">paymentamount:</label>
<input
type="text"
class="form-control"
id="paymentamount"
formControlName="paymentamount"
/>
</div> -->
<div class="form-group mb-3">
<label class="text-primary" for="inputvalue5">External or CMC Staff:</label>
<select class="form-control" id="inputvalue5" formControlName="inputvalue5" (change)="calculateTotalPrice()">
<option value="External">External</option>
<option value="CMCStaff">CMC Staff</option>
</select>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('inputvalue5').hasError('required')
"
class="error-message"
>This field is required.</small
>
</div>
<div class="form-group mb-3">
<label for="registrationType">Registration Type:</label>
<select
id="registrationType"
class="form-control"
formControlName="registrationType"
(change)="calculateTotalPrice()"
>
<!-- <option value="NA">NA</option> -->
<option
*ngIf="registrationForm.get('istacMember').value === 'Yes'"
value="Online"
>
Online ₹ 500 <span *ngIf="registrationForm.get('inputvalue5').value === 'External'">+ 18% GST</span>
</option>
<option value="Symposium">Symposium ₹ 1000 <span *ngIf="registrationForm.get('inputvalue5').value === 'External'">+ 18% GST</span></option>
<option value="Workshop">Workshop ₹ 3500 <span *ngIf="registrationForm.get('inputvalue5').value === 'External'">+ 18% GST</span></option>
<option value="SymposiumAndWorkshop">
Symposium & Workshop ₹ 4500 <span *ngIf="registrationForm.get('inputvalue5').value === 'External'">+ 18% GST</span>
</option>
</select>
</div>
<!-- Paying Towards -->
<div class="form-group mb-3">
<label class="text-primary" for="ToWards"
>Paying Towards: *</label
>
<input
class="form-control"
type="text"
placeholder="Workshop Fee"
id="ToWards"
formControlName="ToWards"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('ToWards').hasError('required')"
class="error-message"
>This field is required.</small
>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('ToWards').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Payment Through (Bank Name) -->
<div class="form-group mb-3">
<label class="text-primary" for="bankname"
>Payment Through: *</label
>
<select
id="bankname"
formControlName="bankname"
class="form-control"
>
<option value="">Select Payment Method</option>
<option value="PAYU">PAYU - Cards, UPI, Wallets, Netbanking</option>
<option value="HDFC">HDFC - Cards</option>
</select>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('bankname').hasError('required')"
class="error-message"
>This field is required.</small
>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('bankname').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<div class="card p-2 mb-3">
<div class="form-group mb-3">
<label for="submitCase"
>Are you interested in submitting a challenging or interesting
case?</label
>
<div class="form-check">
<input
class="form-check-input"
type="radio"
id="submitCaseYes"
value="Yes"
formControlName="submitCase"
/>
<label class="form-check-label" for="flexRadioDefault1">
Yes
</label>
</div>
<div class="form-check">
<input
class="form-check-input"
type="radio"
id="submitCaseNo"
value="No"
formControlName="submitCase"
/>
<label class="form-check-label" for="flexRadioDefault2">
No
</label>
</div>
</div>
</div>
<div *ngIf="registrationForm.get('submitCase').value === 'Yes'">
<p>
Submit your abstract to
<a href="mailto:traumasurg.academic@cmcvellore.ac.in"
>traumasurg.academic@cmcvellore.ac.in</a
>
</p>
</div>
<!-- User opt for 80G -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="Allow80G" class="text-primary"
>User opt for 80G: *</label
>
<select
class="form-control"
id="Allow80G"
formControlName="Allow80G"
>
<option value="Y">Y - Yes</option>
<option value="N">N - No</option>
</select>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('Allow80G').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- PAN Card No -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="PanCardNo">PAN Card No:</label>
<input
class="form-control"
type="text"
id="PanCardNo"
formControlName="PanCardNo"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('PanCardNo').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Amount Contains GST (hasgst) -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="hasgst" class="text-primary"
>Amount Contains GST:</label
>
<select class="form-control" id="hasgst" formControlName="hasgst">
<option value="Y">Y - Yes</option>
<option value="N">N - No</option>
</select>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('hasgst').hasError('required')"
class="error-message"
>This field is required.</small
>
</div>
<!-- GST Registered / Unregistered -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="GSTReg">GST Registered / Unregistered:</label>
<input
class="form-control"
type="text"
id="GSTReg"
formControlName="GSTReg"
/>
</div>
<!-- GST Number -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="gstnumber">GST Number:</label>
<input
class="form-control"
type="text"
id="gstnumber"
formControlName="gstnumber"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('gstnumber').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- GST Registered Mobile No -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="gstmobileno">GST Registered Mobile No:</label>
<input
class="form-control"
type="text"
id="gstmobileno"
formControlName="gstmobileno"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('gstmobileno').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- GST Registered Email ID -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="gstemailid">GST Registered Email ID:</label>
<input
class="form-control"
type="text"
id="gstemailid"
formControlName="gstemailid"
/>
<small
class="form-text text-muted"
*ngIf="registrationForm.get('gstemailid').hasError('maxLength')"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Additional Field Caption 1 -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="inputcaption1">Additional Field Caption 1:</label>
<input
class="form-control"
type="text"
id="inputcaption1"
formControlName="inputcaption1"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('inputcaption1').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Additional Field Caption 1 Value -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="inputvalue1">Additional Field Caption 1 Value:</label>
<input
class="form-control"
type="text"
id="inputvalue1"
formControlName="inputvalue1"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('inputvalue1').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Additional Field Caption 2 -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="inputcaption2">Additional Field Caption 2:</label>
<input
class="form-control"
type="text"
id="inputcaption2"
formControlName="inputcaption2"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('inputcaption2').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<!-- Additional Field Caption 2 Value -->
<div class="form-group mb-3" *ngIf="shouldDisplayElement">
<label for="inputvalue2">Additional Field Caption 2 Value:</label>
<input
class="form-control"
type="text"
id="inputvalue2"
formControlName="inputvalue2"
/>
<small
class="form-text text-muted"
*ngIf="
registrationForm.get('inputvalue2').hasError('maxLength')
"
class="error-message"
>Maximum length exceeded.</small
>
</div>
<div class="mb-3">
<p>Total Price : ₹ {{ totalPrice }}</p>
</div>
<div class="alert alert-danger mb-2" *ngIf="getInvalidFields().length > 0">
Please correct the following fields:
<ul>
<li *ngFor="let field of getInvalidFields()">
{{ field == 'inputvalue5' ? 'External or CMC Staff:' : field }}
</li>
</ul>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="row mt-3" *ngIf="paymentInfo.ResultCode == '0'">
<div class="col-lg">
<div class="container">
<div class="card">
<div class="card-body">
<h2 class="text-muted text-primary">
The payment link has been generated successfully. Kindly jot down
the information or capture a screenshot of the details, and then
proceed to click the provided link below.
</h2>
<br />
<div class="container">
<p>Registration: {{ paymentInfo.Registration }}</p>
<p>Transaction ID: {{ paymentInfo.Transid }}</p>
<p>Result Code: {{ paymentInfo.ResultCode }}</p>
<p>Result: {{ paymentInfo.Result }}</p>
<a class="btn btn-primary m-2" [href]="paymentInfo.URL">Payment URL</a>
<br>
<br>
<br>
<br>
<p>
<!-- <a href="/">Go Home</a> | -->
<a href="javascript:void(0);" (click)="printPage()">Print</a> |
<!-- <a href="javascript:void(0);" (click)="goBack()">Go Back</a> -->
</p>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RegisterComponent } from './register.component';
describe('RegisterComponent', () => {
let component: RegisterComponent;
let fixture: ComponentFixture<RegisterComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ RegisterComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(RegisterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,257 @@
import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { ActivatedRoute } from "@angular/router";
import { DataService, PaymentInfo } from "src/app/data.service";
import { XmlParserService } from "src/app/xml-parser.service";
@Component({
selector: "app-register",
templateUrl: "./register.component.html",
styleUrls: ["./register.component.scss"],
})
export class RegisterComponent implements OnInit {
registrationForm: FormGroup;
shouldDisplayElement = false;
totalPrice: number = 0;
constructor(
private fb: FormBuilder,
private route: ActivatedRoute,
private dataService: DataService,
private xmlParserService: XmlParserService
) {}
eventId: string;
event: any;
events = [];
paymentInfo: PaymentInfo;
ngOnInit() {
this.events = this.dataService.events;
this.paymentInfo = new PaymentInfo(); // Initialize the instance
this.route.params.subscribe((params) => {
this.eventId = params["id"]; // 'id' should match the route parameter name defined in your routing configuration
this.event = this.findEventById(this.eventId);
});
this.registrationForm = this.fb.group({
conferencecode: ["", [Validators.required, Validators.maxLength(10)]],
conferenceyear: ["", [Validators.required, Validators.maxLength(4)]],
bankname: ["", [Validators.required, Validators.maxLength(20)]],
remoteip: ["", [Validators.maxLength(15)]],
regno: ["", [Validators.required, Validators.maxLength(20)]],
candidatename: ["", [Validators.required, Validators.maxLength(80)]],
nameinreceipt: ["", [Validators.required, Validators.maxLength(150)]],
address1: ["", [Validators.maxLength(200)]],
address2: ["", [Validators.maxLength(200)]],
city: ["", [Validators.maxLength(100)]], // CMC Mission
state: ["12345", [Validators.maxLength(100)]], // CMC Mission ID
country: ["", [Validators.maxLength(100)]],
pincode: ["", [Validators.maxLength(10)]],
phone: ["", [Validators.required, Validators.maxLength(20)]],
mobile: ["", [Validators.maxLength(20)]],
email: ["", [Validators.maxLength(70)]],
foodtype: ["", [Validators.maxLength(2)]],
participanttype: ["", [Validators.maxLength(30)]],
practicetype: ["", [Validators.maxLength(80)]],
accompanymembers: ["", [Validators.maxLength(2)]],
paymentamount: ["", [Validators.required]],
ToWards: ["", [Validators.required, Validators.maxLength(200)]],
Allow80G: ["N", [Validators.required]],
PanCardNo: ["", [Validators.maxLength(10)]],
hasgst: ["N", [Validators.required]],
GSTReg: [""],
gstnumber: ["", [Validators.maxLength(20)]],
gstmobileno: ["", [Validators.maxLength(12)]],
gstemailid: ["", [Validators.maxLength(100)]],
inputcaption1: ["", [Validators.maxLength(50)]], // isPaymentDone
inputvalue1: ["", [Validators.maxLength(200)]], // designation
inputcaption2: ["", [Validators.maxLength(50)]], // placeOfWork
inputvalue2: ["", [Validators.maxLength(200)]], // medicalCollegeName
inputcaption3: ["", [Validators.maxLength(50)]], // hospitalName
inputvalue3: ["", [Validators.maxLength(200)]], // istacMember
inputcaption4: ["", [Validators.maxLength(50)]], // istacMemberID
inputvalue4: ["", [Validators.maxLength(200)]], // registrationType
inputcaption5: ["", [Validators.maxLength(50)]], // submitCase
inputvalue5: ["", [Validators.maxLength(200), Validators.required]], // External or CMC staff
isPaymentDone: ["N", Validators.required],
designation: [""],
placeOfWork: ["None"],
medicalCollegeName: [""],
hospitalName: [""],
istacMember: ["No"],
istacMemberID: [""],
registrationType: ["", Validators.required],
submitCase: ["No"],
});
// Set initial values for the form
this.registrationForm.patchValue({
conferencecode: this.event.code,
conferenceyear: this.event.year,
regno: this.generateRandomHash(9),
Allow80G: "N",
hasgst: "N",
});
this.registrationForm
.get("nameinreceipt")
.valueChanges.subscribe((newValue) => {
console.log("Input value changed:", newValue);
// You can perform actions here based on the new input value
this.registrationForm.patchValue({
candidatename: newValue,
});
});
}
findEventById(eventId): any {
return this.events.find((event) => event.id == eventId);
}
generateRandomHash(length: number): string {
const characters = "012345G0VARDHAN6789";
let randomHash = "";
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * characters.length);
randomHash += characters.charAt(randomIndex);
}
return randomHash;
}
calculateTotalPrice() {
const registrationType =
this.registrationForm.get("registrationType").value;
const isCmcStaff = this.registrationForm.get("inputvalue5").value;
if (isCmcStaff === "CMCStaff") {
// Exclude GST for CMC Staff
if (registrationType === "Online") {
this.totalPrice = 500;
} else if (registrationType === "Symposium") {
this.totalPrice = 1000;
} else if (registrationType === "Workshop") {
this.totalPrice = 3500;
} else if (registrationType === "SymposiumAndWorkshop") {
this.totalPrice = 4500;
} else {
this.totalPrice = 0;
}
} else {
// Apply GST for External
if (registrationType === "Online") {
this.totalPrice = 500 + 0.18 * 500; // ₹ 500 + 18% GST
} else if (registrationType === "Symposium") {
this.totalPrice = 1000 + 0.18 * 1000; // ₹ 1000 + 18% GST
} else if (registrationType === "Workshop") {
this.totalPrice = 3500 + 0.18 * 3500; // ₹ 3500 + 18% GST
} else if (registrationType === "SymposiumAndWorkshop") {
this.totalPrice = 4500 + 0.18 * 4500; // ₹ 4500 + 18% GST
} else {
this.totalPrice = 0;
}
}
this.registrationForm.patchValue({
paymentamount: this.totalPrice,
ToWards: registrationType,
});
}
confirmData(): boolean {
return confirm("Are you sure you want to proceed with the data?");
}
printPage() {
window.print(); // Opens the browser's print dialog
}
getInvalidFields() {
const invalidFields = [];
Object.keys(this.registrationForm.controls).forEach((controlName) => {
const control = this.registrationForm.get(controlName);
if (control.invalid) {
invalidFields.push(controlName);
}
});
return invalidFields;
}
onSubmit() {
const formData = this.registrationForm.value;
(formData.inputcaption1 = formData.isPaymentDone),
(formData.inputvalue1 = formData.designation),
(formData.inputcaption2 = formData.placeOfWork),
(formData.inputvalue2 = formData.medicalCollegeName),
(formData.inputcaption3 = formData.hospitalName),
(formData.inputvalue3 = formData.istacMember),
(formData.inputcaption4 = formData.istacMemberID),
(formData.inputvalue4 = formData.registrationType),
(formData.inputcaption5 = formData.submitCase),
// (formData.candidatename = formData.nameinreceipt);
console.log("formData ", formData);
setTimeout(() => {
if (this.registrationForm.valid) {
if (this.confirmData()) this.sendSOAPRequest(formData);
} else {
alert("Please fill out all required fields correctly.");
}
}, 500);
}
sendSOAPRequest(formData: any) {
this.dataService.sendSOAPRequest(formData).subscribe(
(res) => {
this.handleSOAPResponse(res);
},
(error) => {
this.handleSOAPError(error);
}
);
}
handleSOAPResponse(res: any) {
console.log(res);
this.paymentInfo = this.xmlParserService.parseXml(res);
if (this.paymentInfo.ResultCode == "0") {
const confData = {
...this.paymentInfo,
...this.registrationForm.value,
};
console.log("conf Data", confData);
this.insertConferenceData(confData);
}
}
handleSOAPError(error: any) {
alert("Something went wrong " + error);
console.error(error);
}
insertConferenceData(confData: any) {
this.dataService.insertConferenceData(confData).subscribe(
(response) => {
console.log("Response from API:", response);
// Handle the response from the API as needed
},
(error) => {
console.error("Error:", error);
// Handle errors
}
);
}
}

View File

@ -0,0 +1,83 @@
<div class="container" *ngIf="queryParams.inputcaption1">
<div class="row">
<div class="col-md-6 offset-md-3 mt-5">
<div class="card" *ngIf="confRegObj.id">
<div class="card-body">
<h5 class="card-title">Conference Information</h5>
<hr />
<table class="table">
<tbody>
<tr>
<th>ID</th>
<td>{{ confRegObj.id }}</td>
</tr>
<tr>
<th>Conference Code</th>
<td>{{ confRegObj.conferencecode }}</td>
</tr>
<tr>
<th>Name</th>
<td>{{ confRegObj.nameinreceipt }}</td>
</tr>
<tr>
<th>Address</th>
<td>{{ confRegObj.address1 }}</td>
</tr>
<tr>
<th>Phone</th>
<td>{{ confRegObj.phone }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-md-6 offset-md-3 mt-5">
<div class="card">
<div class="card-body">
<h5 class="card-title">
Payment successful! Your registration for the Symposium is complete.
</h5>
<p class="card-text">
Reg No: {{ queryParams.regno }}
<br />
Payment status:
<span class="text-info">{{
queryParams.inputcaption1 == "Y" ? "SUCCESS" : "UNKNOWN"
}}</span>
<br />
Transaction ID: {{ queryParams.responseTransid }}
</p>
<!-- Add the links here -->
<p>
<a href="/">Go Home</a> |
<a
href="javascript:void(0);"
class="btn btn-primary"
(click)="printPage()"
>Print</a
>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="container" *ngIf="!queryParams.inputcaption1">
<div class="row">
<div class="col-md-6 offset-md-3 mt-5">
<div class="card">
<div class="card-body">
<h5 class="card-title">Something went wrong..</h5>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RegistrationStatusComponent } from './registration-status.component';
describe('RegistrationStatusComponent', () => {
let component: RegistrationStatusComponent;
let fixture: ComponentFixture<RegistrationStatusComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ RegistrationStatusComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(RegistrationStatusComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,65 @@
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { DataService } from "src/app/data.service";
@Component({
selector: "app-registration-status",
templateUrl: "./registration-status.component.html",
styleUrls: ["./registration-status.component.scss"],
})
export class RegistrationStatusComponent implements OnInit {
queryParams: any = {};
confRegObj: any = {};
constructor(
private route: ActivatedRoute,
private dataService: DataService
) {}
printPage() {
window.print(); // Opens the browser's print dialog
}
ngOnInit() {
// Access the query parameters
this.queryParams.regno = this.route.snapshot.queryParamMap.get("regno");
this.queryParams.inputcaption1 =
this.route.snapshot.queryParamMap.get("status");
this.queryParams.responseTransid =
this.route.snapshot.queryParamMap.get("transid");
// this.queryParams.inputvalue5 =
// this.route.snapshot.queryParamMap.get("message");
if (this.queryParams.inputcaption1 == "Y") {
this.dataService
.getConferenceDataByRegno(this.queryParams.regno)
.subscribe((res: any) => {
this.confRegObj = res;
console.log(res);
this.confRegObj = this.updateObject(
this.confRegObj,
this.queryParams
);
setTimeout(() => {
this.updateConf(this.confRegObj);
}, 1000);
});
}
}
updateObject(target: any, updates: Record<string, any>): any {
target = { ...target, ...updates };
return target;
}
updateConf(data: any) {
console.log("data ", data);
this.dataService.insertConferenceData(data).subscribe((res) => {
console.log(res);
});
}
}

View File

@ -0,0 +1,40 @@
<section class="bg-login d-flex align-items-center">
<div class="container">
<div class="row justify-content-center mt-4">
<div class="col-lg-4">
<div class="bg-white p-4 mt-5 rounded">
<div class="text-center">
<h4 class="fw-bold mb-3">Globing</h4>
</div>
<form class="login-form">
<div class="row">
<div class="col-lg-12 mt-2">
<input type="text" class="form-control" placeholder="First Name" required="">
</div>
<div class="col-lg-12 mt-2">
<input type="email" class="form-control" placeholder="Email" required="">
</div>
<div class="col-lg-12 mt-2">
<input type="password" class="form-control" placeholder="Password" required="">
</div>
<div class="col-lg-12 mt-2">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="flexCheckDefault">
<label class="form-check-label" for="flexCheckDefault">
I Accept <a href="#">Terms And Condition</a>
</label>
</div>
</div>
<div class="col-lg-12 mt-4">
<button class="btn btn-primary w-100">Register</button>
</div>
</div>
</form>
</div>
<div class="text-center mt-3">
<p><small class="text-white me-2">Already have an account ?</small> <a routerLink="/login" class="text-white fw-bold">Sign in</a></p>
</div>
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SignupComponent } from './signup.component';
describe('SignupComponent', () => {
let component: SignupComponent;
let fixture: ComponentFixture<SignupComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SignupComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(SignupComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.scss']
})
export class SignupComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@ -44,7 +44,7 @@ export class AuthenticationService {
this.storage.removeItem(this.JWT_TOKEN_STORAGE_KEY);
this.storage.removeItem(this.USER_STORAGE_KEY);
this.storage.removeItem("users");
this.router.navigateByUrl('/login');
this.router.navigateByUrl('/dashboard/login');
}

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { EventService } from './event.service';
describe('EventService', () => {
let service: EventService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(EventService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,68 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root'
})
export class EventService {
private apiUrl = environment.apiUrl+'/api/events'; // Replace with your API endpoint
constructor(private http: HttpClient) { }
// Fetch all events
getEvents(): Observable<any[]> {
return this.http.get<any[]>(this.apiUrl)
.pipe(
catchError(this.handleError<any[]>('getEvents', []))
);
}
// Fetch a single event by id
getEvent(id: number): Observable<any> {
const url = `${this.apiUrl}/${id}`;
return this.http.get<any>(url)
.pipe(
catchError(this.handleError<any>(`getEvent id=${id}`))
);
}
// Create a new event
createEvent(event: any): Observable<any> {
return this.http.post<any>(this.apiUrl, event, this.httpOptions)
.pipe(
catchError(this.handleError<any>('createEvent'))
);
}
// Update an existing event
updateEvent(id: number, event: any): Observable<any> {
const url = `${this.apiUrl}/${id}`;
return this.http.put<any>(url, event, this.httpOptions)
.pipe(
catchError(this.handleError<any>('updateEvent'))
);
}
// Delete an event by id
deleteEvent(id: number): Observable<any> {
const url = `${this.apiUrl}/${id}`;
return this.http.delete<any>(url)
.pipe(
catchError(this.handleError<any>('deleteEvent'))
);
}
private httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(`${operation} failed: ${error.message}`);
return of(result as T);
};
}
}

View File

@ -0,0 +1,87 @@
<!-- STRAT TESTIMONIAL -->
<section class="section bg-client" id="testi">
<div class="container">
<div class="row justify-content-center mt-5 mb-5">
<div class="col-lg-12">
<owl-carousel-o [options]="customOptions">
<ng-template carouselSlide>
<div class="text-center w-75 mx-auto">
<div class="testi-icon text-white">
<i class="ti-quote-left"></i>
</div>
<div class="mt-3">
<p class="user-review text-center">Risus cubilia etiam parturient augue nostra
sodales sit aptent venenatis magna sapien
ante hendrerit ullamcorper tincidunt urna eget Ante feugiat.</p>
<div class="">
<img src="assets/images/testi/testi-1.jpg" alt=""
class="rounded-circle testi-user mx-auto d-block">
</div>
<p class="testi-user-name text-center text-white mb-0 mt-4">- John Litts,
Globing</p>
<p class="text-muted">
<span class="ti-star text-warning"></span>
<span class="ti-star text-warning"></span>
<span class="ti-star text-warning"></span>
<span class="ti-star text-warning"></span>
<span class="ti-star text-warning"></span>
</p>
</div>
</div>
</ng-template>
<ng-template carouselSlide>
<div class="text-center w-75 mx-auto">
<div class="testi-icon text-white">
<i class="ti-quote-left"></i>
</div>
<div class="mt-3">
<p class="user-review text-center">Risus cubilia etiam parturient augue nostra
sodales sit aptent venenatis ullamcorper tincidunt urna, eget magna sapien
ante hendrerit Ante feugiat.</p>
<div class="">
<img src="assets/images/testi/testi-2.jpg" alt=""
class="rounded-circle testi-user mx-auto d-block">
</div>
<p class="testi-user-name text-center text-white mb-0 mt-4">- John Litts,
Globing</p>
<p class="text-muted">
<span class="ti-star text-warning"></span>
<span class="ti-star text-warning"></span>
<span class="ti-star text-warning"></span>
<span class="ti-star text-warning"></span>
<span class="ti-star"></span>
</p>
</div>
</div>
</ng-template>
<ng-template carouselSlide>
<div class="text-center w-75 mx-auto">
<div class="testi-icon text-white">
<i class="ti-quote-left"></i>
</div>
<div class="mt-3">
<p class="user-review text-center">Risus cubilia etiam parturient augue nostra
sodales sit aptent venenatis magna ullamcorper tincidunt urna, eget sapien
ante hendrerit Ante feugiat.</p>
<div class="">
<img src="assets/images/testi/testi-3.jpg" alt=""
class="rounded-circle testi-user mx-auto d-block">
</div>
<p class="testi-user-name text-center text-white mb-0 mt-4">- John Litts,
Globing</p>
<p class="text-muted">
<span class="ti-star text-warning"></span>
<span class="ti-star text-warning"></span>
<span class="ti-star text-warning"></span>
<span class="ti-star text-warning"></span>
<span class="ti-star text-warning"></span>
</p>
</div>
</div>
</ng-template>
</owl-carousel-o>
</div>
</div>
</div>
</section>
<!-- END TESTIMONIAL -->

Some files were not shown because too many files have changed in this diff Show More