Add Twilio SMS service, enhance booking/confirmation flow, and update home UI
All checks were successful
Build and Publish / build (push) Successful in 3m16s

- Add TwilioService for SMS notifications
- Extend PrenotazioneService and ConfermaServiceImpl with new booking/confirmation logic
- Add phone number support in UtenteAppService and UtenteAppServiceImpl
- Update PrenotazioneRepository with custom queries
- Enhance ConfermaResource and PrenotazioneResource REST endpoints
- Add MailService improvements
- Update application.yml with new config entries
- Update home page (home.vue, home.json, global.scss) and add Artegna logo

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Simone Bierti
2026-04-11 15:34:42 +02:00
parent 78d3e17d02
commit 45968b28e2
18 changed files with 253 additions and 22 deletions

View File

@@ -80,6 +80,9 @@ dependencies {
implementation "org.hibernate.orm:hibernate-jcache"
implementation "org.hibernate.validator:hibernate-validator"
implementation "org.postgresql:postgresql"
implementation "io.seruco.encoding:base62:0.1.3"
implementation "com.twilio.sdk:twilio:11.3.6"
testImplementation(libs.archunit.junit5.api) {
exclude group: 'org.slf4j', module: 'slf4j-api'
}

View File

@@ -1,6 +1,8 @@
package it.sw.pa.comune.artegna.repository;
import it.sw.pa.comune.artegna.domain.Prenotazione;
import it.sw.pa.comune.artegna.domain.enumeration.StatoPrenotazione;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.springframework.data.domain.Page;
@@ -39,4 +41,6 @@ public interface PrenotazioneRepository extends JpaRepository<Prenotazione, Long
"select prenotazione from Prenotazione prenotazione left join fetch prenotazione.utente left join fetch prenotazione.struttura where prenotazione.id =:id"
)
Optional<Prenotazione> findOneWithToOneRelationships(@Param("id") Long id);
Long id(Long id);
}

View File

@@ -117,4 +117,13 @@ public class MailService {
LOG.debug("Sending password reset email to '{}'", user.getEmail());
sendEmailFromTemplateSync(user, "mail/passwordResetEmail", "email.reset.title");
}
// crea un metodo per l'invio di email che la prenotazione è stata confermata o rifiutata
@Async
public void sendBookingConfirmationEmail(User user, boolean confirmed) {
String templateName = confirmed ? "mail/bookingConfirmedEmail" : "mail/bookingRejectedEmail";
String titleKey = confirmed ? "email.booking.confirmed.title" : "email.booking.rejected.title";
LOG.debug("Sending {} email to '{}'", confirmed ? "confirmation" : "rejection", user.getEmail());
sendEmailFromTemplateSync(user, templateName, titleKey);
}
}

View File

@@ -1,6 +1,7 @@
package it.sw.pa.comune.artegna.service;
import it.sw.pa.comune.artegna.service.dto.PrenotazioneDTO;
import java.util.List;
import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

View File

@@ -0,0 +1,37 @@
package it.sw.pa.comune.artegna.service;
import com.twilio.Twilio;
import com.twilio.converter.Promoter;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;
import java.math.BigDecimal;
import java.net.URI;
import org.springframework.beans.factory.annotation.Value;
public class TwilioService {
@Value("${twilio.account.sid}")
private String accountSid;
@Value("${twilio.auth.token}")
private String authToken;
@Value("${twilio.whatsapp.number}")
private String fromWhatsAppNumber;
public TwilioService() {
// Initialize Twilio with account credentials
Twilio.init(accountSid, authToken);
}
public String sendWhatsAppMessage(String to, String messageBody) {
// Send a message via Twilio's API
Message message = Message.creator(
new PhoneNumber("whatsapp:" + to), // Recipient's WhatsApp number
new PhoneNumber(fromWhatsAppNumber), // Twilio WhatsApp number
messageBody
).create(); // Message body
return message.getSid(); // Return message SID to track status
}
}

View File

@@ -71,4 +71,6 @@ public interface UtenteAppService {
* @param id the id of the entity.
*/
void delete(Long id);
UtenteAppDTO fetchUtenteAppFromUser();
}

View File

@@ -1,10 +1,22 @@
package it.sw.pa.comune.artegna.service.impl;
import static it.sw.pa.comune.artegna.domain.enumeration.TipoEventoNotifica.ANNULLAMENTO;
import io.seruco.encoding.base62.Base62;
import it.sw.pa.comune.artegna.domain.Conferma;
import it.sw.pa.comune.artegna.domain.Prenotazione;
import it.sw.pa.comune.artegna.domain.User;
import it.sw.pa.comune.artegna.domain.enumeration.StatoPrenotazione;
import it.sw.pa.comune.artegna.domain.enumeration.TipoConferma;
import it.sw.pa.comune.artegna.repository.ConfermaRepository;
import it.sw.pa.comune.artegna.repository.PrenotazioneRepository;
import it.sw.pa.comune.artegna.service.ConfermaService;
import it.sw.pa.comune.artegna.service.UserService;
import it.sw.pa.comune.artegna.service.UtenteAppService;
import it.sw.pa.comune.artegna.service.dto.ConfermaDTO;
import it.sw.pa.comune.artegna.service.dto.UtenteAppDTO;
import it.sw.pa.comune.artegna.service.mapper.ConfermaMapper;
import it.sw.pa.comune.artegna.service.mapper.UserMapper;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
@@ -14,6 +26,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -30,19 +43,67 @@ public class ConfermaServiceImpl implements ConfermaService {
private final ConfermaMapper confermaMapper;
public ConfermaServiceImpl(ConfermaRepository confermaRepository, ConfermaMapper confermaMapper) {
private final PrenotazioneRepository prenotazioneRepository;
private final UtenteAppService utenteAppService;
public ConfermaServiceImpl(
ConfermaRepository confermaRepository,
ConfermaMapper confermaMapper,
PrenotazioneRepository prenotazioneRepository,
UtenteAppService utenteAppService
) {
this.confermaRepository = confermaRepository;
this.confermaMapper = confermaMapper;
this.prenotazioneRepository = prenotazioneRepository;
this.utenteAppService = utenteAppService;
}
@Override
public ConfermaDTO save(ConfermaDTO confermaDTO) {
LOG.debug("Request to save Conferma : {}", confermaDTO);
confermaDTO.setConfermataDa(utenteAppService.fetchUtenteAppFromUser());
Conferma conferma = confermaMapper.toEntity(confermaDTO);
conferma = confermaRepository.save(conferma);
Long idPrenotazione = null;
if (conferma.getId() != null) {
idPrenotazione = conferma.getId();
conferma.setId(null);
conferma.setCodice(createCodice());
if (conferma.getTipoConferma() == null) {
conferma.setTipoConferma(TipoConferma.RIFIUTATA);
}
}
conferma = confermaRepository.saveAndFlush(conferma);
if (idPrenotazione != null) {
Prenotazione prenotazioneCollegata = prenotazioneRepository.findById(idPrenotazione).orElse(null);
if (prenotazioneCollegata != null) {
switch (conferma.getTipoConferma()) {
case CONFERMATA:
prenotazioneCollegata.setStato(StatoPrenotazione.CONFERMATA);
break;
case RIFIUTATA:
prenotazioneCollegata.setStato(StatoPrenotazione.ANNULLATA);
break;
default:
throw new IllegalArgumentException("Tipo conferma non valido: " + conferma.getTipoConferma());
}
prenotazioneCollegata.setConferma(conferma);
prenotazioneRepository.saveAndFlush(prenotazioneCollegata);
}
}
return confermaMapper.toDto(conferma);
}
private String createCodice() {
Base62 base62 = Base62.createInstance();
String currentDateTime = String.valueOf(java.time.Instant.now().toEpochMilli());
return new String(
base62.encode(currentDateTime.getBytes(java.nio.charset.StandardCharsets.UTF_8)),
java.nio.charset.StandardCharsets.UTF_8
);
}
@Override
public ConfermaDTO update(ConfermaDTO confermaDTO) {
LOG.debug("Request to update Conferma : {}", confermaDTO);

View File

@@ -1,10 +1,12 @@
package it.sw.pa.comune.artegna.service.impl;
import it.sw.pa.comune.artegna.domain.Prenotazione;
import it.sw.pa.comune.artegna.domain.enumeration.StatoPrenotazione;
import it.sw.pa.comune.artegna.repository.PrenotazioneRepository;
import it.sw.pa.comune.artegna.service.PrenotazioneService;
import it.sw.pa.comune.artegna.service.dto.PrenotazioneDTO;
import it.sw.pa.comune.artegna.service.mapper.PrenotazioneMapper;
import java.util.List;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@@ -1,6 +1,8 @@
package it.sw.pa.comune.artegna.service.impl;
import it.sw.pa.comune.artegna.domain.Prenotazione;
import it.sw.pa.comune.artegna.domain.Struttura;
import it.sw.pa.comune.artegna.domain.enumeration.StatoPrenotazione;
import it.sw.pa.comune.artegna.repository.StrutturaRepository;
import it.sw.pa.comune.artegna.service.StrutturaService;
import it.sw.pa.comune.artegna.service.dto.StrutturaDTO;
@@ -8,6 +10,7 @@ import it.sw.pa.comune.artegna.service.mapper.StrutturaMapper;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

View File

@@ -2,8 +2,10 @@ package it.sw.pa.comune.artegna.service.impl;
import it.sw.pa.comune.artegna.domain.UtenteApp;
import it.sw.pa.comune.artegna.repository.UtenteAppRepository;
import it.sw.pa.comune.artegna.service.UserService;
import it.sw.pa.comune.artegna.service.UtenteAppService;
import it.sw.pa.comune.artegna.service.dto.UtenteAppDTO;
import it.sw.pa.comune.artegna.service.mapper.UserMapper;
import it.sw.pa.comune.artegna.service.mapper.UtenteAppMapper;
import java.util.LinkedList;
import java.util.List;
@@ -13,6 +15,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -29,9 +32,20 @@ public class UtenteAppServiceImpl implements UtenteAppService {
private final UtenteAppMapper utenteAppMapper;
public UtenteAppServiceImpl(UtenteAppRepository utenteAppRepository, UtenteAppMapper utenteAppMapper) {
private final UserService userService;
private final UserMapper userMapper;
public UtenteAppServiceImpl(
UtenteAppRepository utenteAppRepository,
UtenteAppMapper utenteAppMapper,
UserService userService,
UserMapper userMapper
) {
this.utenteAppRepository = utenteAppRepository;
this.utenteAppMapper = utenteAppMapper;
this.userService = userService;
this.userMapper = userMapper;
}
@Override
@@ -95,4 +109,12 @@ public class UtenteAppServiceImpl implements UtenteAppService {
LOG.debug("Request to delete UtenteApp : {}", id);
utenteAppRepository.deleteById(id);
}
@Override
public UtenteAppDTO fetchUtenteAppFromUser() {
String currentLogin = SecurityContextHolder.getContext().getAuthentication().getName();
//User currentUser = userService.getUserWithAuthoritiesByLogin(currentLogin).orElseThrow();
UtenteAppDTO utenteAppDTO = utenteAppRepository.findByUsername(currentLogin).map(utenteAppMapper::toDto).orElseThrow();
return utenteAppDTO;
}
}

View File

@@ -1,13 +1,18 @@
package it.sw.pa.comune.artegna.web.rest;
import it.sw.pa.comune.artegna.domain.User;
import it.sw.pa.comune.artegna.repository.ConfermaRepository;
import it.sw.pa.comune.artegna.service.ConfermaQueryService;
import it.sw.pa.comune.artegna.service.ConfermaService;
import it.sw.pa.comune.artegna.service.UserService;
import it.sw.pa.comune.artegna.service.criteria.ConfermaCriteria;
import it.sw.pa.comune.artegna.service.dto.ConfermaDTO;
import it.sw.pa.comune.artegna.service.dto.UtenteAppDTO;
import it.sw.pa.comune.artegna.service.mapper.UserMapper;
import it.sw.pa.comune.artegna.web.rest.errors.BadRequestAlertException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.Principal;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -18,6 +23,8 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import tech.jhipster.web.util.HeaderUtil;
@@ -44,14 +51,22 @@ public class ConfermaResource {
private final ConfermaQueryService confermaQueryService;
private final UserService userService;
private final UserMapper userMapper;
public ConfermaResource(
ConfermaService confermaService,
ConfermaRepository confermaRepository,
ConfermaQueryService confermaQueryService
ConfermaQueryService confermaQueryService,
UserService userService,
UserMapper userMapper
) {
this.confermaService = confermaService;
this.confermaRepository = confermaRepository;
this.confermaQueryService = confermaQueryService;
this.userService = userService;
this.userMapper = userMapper;
}
/**
@@ -62,11 +77,18 @@ public class ConfermaResource {
* @throws URISyntaxException if the Location URI syntax is incorrect.
*/
@PostMapping("")
public ResponseEntity<ConfermaDTO> createConferma(@RequestBody ConfermaDTO confermaDTO) throws URISyntaxException {
public ResponseEntity<ConfermaDTO> createConferma(@RequestBody ConfermaDTO confermaDTO, @AuthenticationPrincipal UserDetails principal)
throws URISyntaxException {
LOG.debug("REST request to save Conferma : {}", confermaDTO);
if (confermaDTO.getId() != null) {
/*if (confermaDTO.getId() != null) {
throw new BadRequestAlertException("A new conferma cannot already have an ID", ENTITY_NAME, "idexists");
}
}*/
String currentLogin = principal.getUsername();
User currentUser = userService.getUserWithAuthoritiesByLogin(currentLogin).orElseThrow();
UtenteAppDTO utenteAppDTO = new UtenteAppDTO();
utenteAppDTO.setInternalUser(userMapper.userToUserDTO(currentUser));
confermaDTO.setConfermataDa(utenteAppDTO);
confermaDTO = confermaService.save(confermaDTO);
return ResponseEntity.created(new URI("/api/confermas/" + confermaDTO.getId()))
.headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, confermaDTO.getId().toString()))

View File

@@ -1,10 +1,16 @@
package it.sw.pa.comune.artegna.web.rest;
import it.sw.pa.comune.artegna.domain.User;
import it.sw.pa.comune.artegna.repository.PrenotazioneRepository;
import it.sw.pa.comune.artegna.security.AuthoritiesConstants;
import it.sw.pa.comune.artegna.service.PrenotazioneQueryService;
import it.sw.pa.comune.artegna.service.PrenotazioneService;
import it.sw.pa.comune.artegna.service.UserService;
import it.sw.pa.comune.artegna.service.UtenteAppService;
import it.sw.pa.comune.artegna.service.criteria.PrenotazioneCriteria;
import it.sw.pa.comune.artegna.service.dto.PrenotazioneDTO;
import it.sw.pa.comune.artegna.service.dto.UserDTO;
import it.sw.pa.comune.artegna.service.dto.UtenteAppDTO;
import it.sw.pa.comune.artegna.web.rest.errors.BadRequestAlertException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -18,8 +24,11 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import tech.jhipster.service.filter.LongFilter;
import tech.jhipster.web.util.HeaderUtil;
import tech.jhipster.web.util.PaginationUtil;
import tech.jhipster.web.util.ResponseUtil;
@@ -44,14 +53,21 @@ public class PrenotazioneResource {
private final PrenotazioneQueryService prenotazioneQueryService;
private final UserService userService;
private final UtenteAppService utenteAppService;
public PrenotazioneResource(
PrenotazioneService prenotazioneService,
PrenotazioneRepository prenotazioneRepository,
PrenotazioneQueryService prenotazioneQueryService
PrenotazioneQueryService prenotazioneQueryService,
UserService userService,
UtenteAppService utenteAppService
) {
this.prenotazioneService = prenotazioneService;
this.prenotazioneRepository = prenotazioneRepository;
this.prenotazioneQueryService = prenotazioneQueryService;
this.userService = userService;
this.utenteAppService = utenteAppService;
}
/**
@@ -152,13 +168,26 @@ public class PrenotazioneResource {
@GetMapping("")
public ResponseEntity<List<PrenotazioneDTO>> getAllPrenotaziones(
PrenotazioneCriteria criteria,
@org.springdoc.core.annotations.ParameterObject Pageable pageable
@org.springdoc.core.annotations.ParameterObject Pageable pageable,
@AuthenticationPrincipal UserDetails principal
) {
LOG.debug("REST request to get Prenotaziones by criteria: {}", criteria);
Page<PrenotazioneDTO> page = prenotazioneQueryService.findByCriteria(criteria, pageable);
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
return ResponseEntity.ok().headers(headers).body(page.getContent());
String currentUser = principal.getUsername();
User user = userService.getUserWithAuthoritiesByLogin(currentUser).orElseThrow();
// switch among user authorities
return switch (user.getAuthorities().stream().findFirst().orElseThrow().getName()) {
case AuthoritiesConstants.INCARICATO, AuthoritiesConstants.ADMIN -> ResponseEntity.ok().body(
prenotazioneQueryService.findByCriteria(criteria, pageable).getContent()
);
default -> {
UtenteAppDTO utenteAppDTO = utenteAppService.fetchUtenteAppFromUser();
criteria.setUtenteId(new LongFilter());
criteria.getUtenteId().setEquals(utenteAppDTO.getId());
yield ResponseEntity.ok().body(prenotazioneQueryService.findByCriteria(criteria, pageable).getContent());
}
};
}
/**

View File

@@ -1,9 +1,13 @@
package it.sw.pa.comune.artegna.web.rest;
import it.sw.pa.comune.artegna.domain.User;
import it.sw.pa.comune.artegna.repository.UtenteAppRepository;
import it.sw.pa.comune.artegna.security.SecurityUtils;
import it.sw.pa.comune.artegna.service.UserService;
import it.sw.pa.comune.artegna.service.UtenteAppService;
import it.sw.pa.comune.artegna.service.dto.UserDTO;
import it.sw.pa.comune.artegna.service.dto.UtenteAppDTO;
import it.sw.pa.comune.artegna.service.mapper.UserMapper;
import it.sw.pa.comune.artegna.web.rest.errors.BadRequestAlertException;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
@@ -16,6 +20,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;
import tech.jhipster.web.util.HeaderUtil;
import tech.jhipster.web.util.ResponseUtil;
@@ -38,9 +44,20 @@ public class UtenteAppResource {
private final UtenteAppRepository utenteAppRepository;
public UtenteAppResource(UtenteAppService utenteAppService, UtenteAppRepository utenteAppRepository) {
private final UserService userService;
private final UserMapper userMapper;
public UtenteAppResource(
UtenteAppService utenteAppService,
UtenteAppRepository utenteAppRepository,
UserService userService,
UserMapper userMapper
) {
this.utenteAppService = utenteAppService;
this.utenteAppRepository = utenteAppRepository;
this.userService = userService;
this.userMapper = userMapper;
}
/**
@@ -51,11 +68,15 @@ public class UtenteAppResource {
* @throws URISyntaxException if the Location URI syntax is incorrect.
*/
@PostMapping("")
public ResponseEntity<UtenteAppDTO> createUtenteApp(@Valid @RequestBody UtenteAppDTO utenteAppDTO) throws URISyntaxException {
public ResponseEntity<UtenteAppDTO> createUtenteApp(
@Valid @RequestBody UtenteAppDTO utenteAppDTO,
@AuthenticationPrincipal UserDetails principal
) throws URISyntaxException {
LOG.debug("REST request to save UtenteApp : {}", utenteAppDTO);
if (utenteAppDTO.getId() != null) {
throw new BadRequestAlertException("A new utenteApp cannot already have an ID", ENTITY_NAME, "idexists");
}
utenteAppDTO = utenteAppService.save(utenteAppDTO);
return ResponseEntity.created(new URI("/api/utente-apps/" + utenteAppDTO.getId()))
.headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, utenteAppDTO.getId().toString()))
@@ -176,7 +197,10 @@ public class UtenteAppResource {
* @throws URISyntaxException if the Location URI syntax is incorrect.
*/
@PostMapping("/current")
public ResponseEntity<UtenteAppDTO> saveCurrentUserProfile(@Valid @RequestBody UtenteAppDTO utenteAppDTO) throws URISyntaxException {
public ResponseEntity<UtenteAppDTO> saveCurrentUserProfile(
@Valid @RequestBody UtenteAppDTO utenteAppDTO,
@AuthenticationPrincipal UserDetails principal
) throws URISyntaxException {
LOG.debug("REST request to save current user profile : {}", utenteAppDTO);
String currentUserLogin = SecurityUtils.getCurrentUserLogin().orElseThrow(() ->
@@ -191,6 +215,10 @@ public class UtenteAppResource {
// Update existing profile
result = utenteAppService.update(utenteAppDTO);
} else {
// collect current user login infos
String currentLogin = principal.getUsername();
User currentUser = userService.getUserWithAuthoritiesByLogin(currentLogin).orElseThrow();
utenteAppDTO.setInternalUser(userMapper.userToUserDTO(currentUser));
// Create new profile
result = utenteAppService.save(utenteAppDTO);
}

View File

@@ -222,3 +222,8 @@ jhipster:
# ===================================================================
# application:
# Twilio configuration
twilio:
accountSid: 'AC0ea64cd2bb43c6ed76e9acdf8087afa7'
authToken: 'cfd2943e70ce09b07ae75f3f1650ccb4'
phoneNumber: YOUR_PHONE_NUMBER

View File

@@ -11,7 +11,9 @@
<div class="alert alert-success" v-if="authenticated">
<span v-if="username">{{ t$('home.logged.message', { username }) }}</span>
</div>
<button class="btn btn-primary jhi-create-entity" v-if="authenticated">
<router-link to="/prenotazione">{{ t$('home.prenotazioni') }}</router-link>
</button>
<div class="alert alert-warning" v-if="authenticated && profileIncomplete && !checkingProfile">
<span>{{ t$('home.profile.incomplete.message') }}</span>
&nbsp;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@@ -61,7 +61,7 @@ Main page styles
display: inline-block;
width: 347px;
height: 497px;
background: url('/content/images/jhipster_family_member_0.svg') no-repeat center top;
background: url('/content/images/artegna.png') no-repeat center top;
background-size: contain;
}
@@ -73,7 +73,7 @@ Main page styles
only screen and (min-resolution: 192dpi),
only screen and (min-resolution: 2dppx) {
.hipster {
background: url('/content/images/jhipster_family_member_0.svg') no-repeat center top;
background: url('/content/images/artegna.png') no-repeat center top;
background-size: contain;
}
}

View File

@@ -1,7 +1,7 @@
{
"home": {
"title": "Benvenuto, Java Hipster!",
"subtitle": "Questa è la tua home page",
"title": "Benvenuto!",
"subtitle": "Questa è l'home page del sistema smARTbooking.",
"logged": {
"message": "Autenticato come \"{ username }\"."
},
@@ -11,7 +11,7 @@
"link": "Completa il profilo"
}
},
"question": "In caso di domande su JHipster:",
"question": "Cosa è possibile fare con smARTbooking:",
"link": {
"homepage": "Homepage JHipster",
"stackoverflow": "JHipster su Stack Overflow",
@@ -20,6 +20,7 @@
"follow": "segui {'@'}jhipster su Twitter"
},
"like": "Se ti piace JHipster, non dimenticarti di darci una stella su",
"github": "GitHub"
"github": "GitHub",
"prenotazioni": "Vai alle tue prenotazioni"
}
}